<?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" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Formcarry Blog]]></title><description><![CDATA[Formcarry blog, useful tutorials about HTML forms and implementations.]]></description><link>https://formcarry.com/blog/</link><image><url>https://formcarry.com/blog/favicon.png</url><title>Formcarry Blog</title><link>https://formcarry.com/blog/</link></image><generator>Ghost 5.22</generator><lastBuildDate>Fri, 28 Nov 2025 10:27:26 GMT</lastBuildDate><atom:link href="https://formcarry.com/blog/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Form abandonment: How to increase your conversion rates]]></title><description><![CDATA[<p>Form abandonment is a common problem that can have a big impact on a business&apos;s success. When a user leaves an online form without completing it, it can lead to lost sales, missed opportunities, and wasted time and money. In fact, nearly 70% of site visitors will abandon</p>]]></description><link>https://formcarry.com/blog/form-abondonment/</link><guid isPermaLink="false">63b90309db889e6d11ce21d3</guid><dc:creator><![CDATA[Nusu Alabuga]]></dc:creator><pubDate>Sat, 07 Jan 2023 09:55:53 GMT</pubDate><media:content url="https://formcarry.com/blog/content/images/2023/01/Frame-52--1-.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://formcarry.com/blog/content/images/2023/01/Frame-52--1-.jpg" alt="Form abandonment: How to increase your conversion rates"><p>Form abandonment is a common problem that can have a big impact on a business&apos;s success. When a user leaves an online form without completing it, it can lead to lost sales, missed opportunities, and wasted time and money. In fact, nearly 70% of site visitors will abandon a form forever if they encounter an issue with it.</p><p>There are many reasons why people abandon forms, including:</p><ul><li>Complexity</li><li>Too much required information</li><li>Security concerns</li><li>Poor user experience</li><li>Lack of perceived value</li></ul><p>It&apos;s important for businesses to track form abandonment and work to improve conversion rates. So, how can you combat form abandonment and increase conversions for your business? Here are some strategies to consider:</p><h2 id="1-make-your-forms-easy-to-use">1. Make Your Forms Easy to Use</h2><p>To reduce form abandonment, it&apos;s important to make your forms easy to use. This means:</p><ul><li>Keeping the number of fields to a minimum</li><li>Using clear and concise language</li><li>Avoiding confusing or unnecessary questions</li></ul><p>According to Convertica, 27% of people abandon online forms due to their length, and 10% abandon forms because of unnecessary questions. By simplifying your forms, you can <a href="https://announcekit.app/blog/improve-customer-experience-online/">improve the user experience</a> and increase the chances of successful form completion.</p><h2 id="2-provide-value-to-the-user">2. Provide Value to the User</h2><p>Make sure the user understands what they will get in return for filling out the form. This could be access to exclusive content, a discount, or something else. Providing value to the user will give them a reason to complete the form and will increase the chances of successful form submission.</p><p>According to Convertica, 29% of people abandon online forms due to security concerns, and 11% abandon forms because of advertisements or upselling. By offering value to the user, you can alleviate their concerns and provide a reason for them to complete the form.</p><h2 id="3-use-a-form-building-and-integration-tool">3. Use a Form Building and Integration Tool</h2><p>Using a form building and integration tool can help streamline the form creation process and make it easier to manage your forms. Formcarry offers a <a href="https://formcarry.com/html-form-generator">free HTML form code generator</a> that allows users to customize and get a beautifully styled HTML form code for their projects. With the Formcarry generator, visitors can create a responsive form with three different style options to choose from.</p><p>If you have a Formcarry account, the output will be a fully functioning form code with no additional configuration needed. Formcarry also offers integrations with Zapier and Webhook support, allowing users to automate their form messages and save them to Google Sheets. Formcarry simplifies the process of building forms, reducing it to just a few minutes.</p><p>In addition to the HTML form generator, Formcarry also provides instant email notifications, spam protection, auto-response messages, customizable thank you pages, file upload capabilities, and the ability to export submissions in CSV or JSON format. These features make Formcarry a valuable tool for improving form conversion rates and streamlining form management.</p><h2 id="4-test-and-optimize-your-forms">4. Test and Optimize Your Forms</h2><p>Testing and optimizing your forms can help you identify and fix any issues that may be causing form abandonment. You can use tools like Google Analytics to track form abandonment rates and see where users are dropping off. You can then use this information to make changes to your forms and improve the user experience.</p><h2 id="5-use-retargeting-and-remarketing-strategies">5. Use Retargeting and Remarketing Strategies</h2><p>Retargeting and remarketing allow you to show targeted ads to users who have abandoned your forms. By using these strategies, you can remind users about your business and encourage them to return and complete the form.</p><p>There are a number of retargeting and remarketing platforms available, including Google AdWords and Facebook Ads. To use these platforms effectively, you&apos;ll need to install a tracking pixel on your website. This will allow you to track users who visit your site and show them targeted ads as they browse the web.</p><h2 id="6-use-visual-aids-and-interactive-elements">6. Use Visual Aids and Interactive Elements</h2><p>Using visual aids like images and videos can help make your forms more engaging and improve the user experience. Interactive elements like progress bars and conditional logic can also help keep users engaged and motivated to complete the form.</p><h2 id="7-make-sure-your-forms-are-mobile-friendly">7. Make Sure Your Forms Are Mobile-Friendly</h2><p>With more and more users accessing the internet from their smartphones, it&apos;s important to make sure your forms are mobile-friendly. This means ensuring that your forms are easy to use on a small screen and that they load quickly.</p><p>According to WPForms, 45% of form data is now submitted from a mobile device. By optimizing your forms for mobile, you can improve the user experience and increase form completion rates.</p><h2 id="8-use-social-proof-and-customer-testimonials">8. Use Social Proof and Customer Testimonials</h2><p>Including social proof and customer testimonials on your forms can help build trust and credibility with users. This can be especially effective if you&apos;re asking users to input sensitive information or make a purchase.</p><h2 id="9-use-marketing-automation-and-lead-nurturing">9. Use Marketing Automation and Lead Nurturing</h2><p>Marketing automation and lead nurturing can help you keep in touch with users who have abandoned your forms. By sending targeted emails and offering helpful resources, you can keep users engaged and increase the chances of them completing the form at a later date.</p><h2 id="conclusion">Conclusion</h2><p>Form abandonment is a common problem that can have a big impact on a business&apos;s success. By following the strategies outlined above, you can combat form abandonment and improve your conversion rates. This will help you capture valuable leads and drive business growth.</p>]]></content:encoded></item><item><title><![CDATA[How to add a contact form to your Shopify website: Step-by-step guide]]></title><description><![CDATA[In this article, we will walk you through the process of adding a contact form to your Shopify website in 7 steps.]]></description><link>https://formcarry.com/blog/how-to-add-shopify-contact-form/</link><guid isPermaLink="false">63a9c9e4282b9243ba7e256d</guid><category><![CDATA[Guides]]></category><dc:creator><![CDATA[Nusu Alabuga]]></dc:creator><pubDate>Tue, 27 Dec 2022 17:03:59 GMT</pubDate><media:content url="https://formcarry.com/blog/content/images/2022/12/blog-cover.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://formcarry.com/blog/content/images/2022/12/blog-cover.jpg" alt="How to add a contact form to your Shopify website: Step-by-step guide"><p>Building a <a href="https://formcarry.com/contact-form-generator">contact form</a> on your Shopify website is a great way to collect customer data and keep in touch with your customers. In this article, we will walk you through the process of adding a contact form to your Shopify website in 7 steps.</p><p>At the end of the tutorial you&#x2019;ll:</p><ul><li>Have a working contact form on your Shopify Store</li><li>Receive email notifications for each new submission using <a href="https://formcarry.com">form backend</a></li><li>Set-up auto-responses for your form</li></ul><h2 id="table-of-contents">Table of Contents:</h2><ul><li><a href="#introduction">Introduction</a></li><li><a href="#step-1create-your-first-form">Create your first form</a> ~30 seconds</li><li><a href="#step-2change-your-form-code-on-your-shopify-store">Change your form code on your Shopify Store</a> ~ 2 minutes</li><li>&#x2003;Option 1: <a href="#option-1modify-existing-form-code">Modify the existing form</a></li><li>&#x2003;Option 2: <a href="#option-2add-your-own-form-code">Add your own form code</a></li><li><a href="#step-3testing-out-your-form">Testing out your form</a> ~ 15 seconds</li><li><a href="#step-4setting-up-email-notifications-for-your-form">Setting up email notifications</a> ~ 20 seconds</li><li><a href="#step-5setting-up-auto-response-emails">Setting up respondent email notifications</a> ~ 20 seconds</li><li><a href="#conclusion">Conclusion</a></li></ul><h2 id="introduction">Introduction</h2><p>Contact forms are critical for any online store to collect essential customer data and improve their customer experience.</p><p>Shopify has built-in form support but it&apos;s very limited, there are a few scenarios where it may not be sufficient for a business&apos;s needs. Some examples include:</p><ul><li>Integration with other tools: If you want to integrate your contact forms with other tools or platforms, such as CRM or email marketing software, Shopify&apos;s built-in forms may not offer the necessary integration options.</li><li>Advanced features: If you need advanced features like file uploads, CAPTCHAs, or multi-page forms, Shopify&apos;s built-in forms may not offer these options.</li><li>Large volume of submissions: If you receive a large volume of form submissions, you may need a more robust solution that can handle the load and offer features like spam protection and automatic responses.</li><li>File uploads: The ability to upload files is an added feature that provides value to your customers and allows your store to gather more relevant information from them.</li></ul><p>That&#x2019;s why many Shopify businesses use Formcarry to process their form data. We offer a simple way to add a custom contact form to your website and process the data through our servers instead of through Shopify. With Formcarry you can automatically receive email notifications for each new submission, set auto-responder messages for the sender, and have built-in spam protection for your forms. You can sign up for a completely free account at <a href="https://formcarry.com/">formcarry.com</a>.</p><h2 id="step-1create-your-first-form">Step 1 - Create your first form</h2><p>Sign up to formcarry <a href="https://app.formcarry.com/register" rel="noopener noreferrer">here</a>. Once you&#x2019;ve logged in to your dashboard, click on the &#x201C;Create Form&#x201D; button to create a new form. After creating your form click on the &#x201C;Setup&#x201D; button and save your unique endpoint URL which we are going to use later</p><figure class="kg-card kg-video-card"><div class="kg-video-container"><video src="https://formcarry.com/blog/content/media/2022/12/create_form_and_copy_endpoint2-1.mp4" poster="https://img.spacergif.org/v1/1270x1080/0a/spacer.png" width="1270" height="1080" playsinline preload="metadata" style="background: transparent url(&apos;https://formcarry.com/blog/content/images/2022/12/media-thumbnail-ember419.jpg&apos;) 50% 50% / cover no-repeat;"></video><div class="kg-video-overlay"><button class="kg-video-large-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button></div><div class="kg-video-player-container"><div class="kg-video-player"><button class="kg-video-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button><button class="kg-video-pause-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"/><rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"/></svg></button><span class="kg-video-current-time">0:00</span><div class="kg-video-time">/<span class="kg-video-duration"></span></div><input type="range" class="kg-video-seek-slider" max="100" value="0"><button class="kg-video-playback-rate">1&#xD7;</button><button class="kg-video-unmute-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"/></svg></button><button class="kg-video-mute-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"/></svg></button><input type="range" class="kg-video-volume-slider" max="100" value="100"></div></div></div></figure><h2 id="step-2change-your-form-code-on-your-shopify-store">Step 2 - Change your form code on your Shopify Store</h2><p>Navigate to your Shopify Admin, click to Online Store from the sidebar, then navigate to the Themes and click the &quot;Customize&quot; button of your current theme. Go into the Edit Code mode then search for &quot;form&quot; and go into the contact-form.liquid, the name may vary in your theme. Open the find panel with CMD+F or CTRL+F and search for the following: &quot;<em>{%-form</em>&quot; once you find it, we&apos;re ready to build your form.</p><figure class="kg-card kg-video-card"><div class="kg-video-container"><video src="https://formcarry.com/blog/content/media/2022/12/finding_form_code_in_shopify.mp4" poster="https://img.spacergif.org/v1/1282x1080/0a/spacer.png" width="1282" height="1080" playsinline preload="metadata" style="background: transparent url(&apos;https://formcarry.com/blog/content/images/2022/12/media-thumbnail-ember431.jpg&apos;) 50% 50% / cover no-repeat;"></video><div class="kg-video-overlay"><button class="kg-video-large-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button></div><div class="kg-video-player-container"><div class="kg-video-player"><button class="kg-video-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button><button class="kg-video-pause-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"/><rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"/></svg></button><span class="kg-video-current-time">0:00</span><div class="kg-video-time">/<span class="kg-video-duration"></span></div><input type="range" class="kg-video-seek-slider" max="100" value="0"><button class="kg-video-playback-rate">1&#xD7;</button><button class="kg-video-unmute-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"/></svg></button><button class="kg-video-mute-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"/></svg></button><input type="range" class="kg-video-volume-slider" max="100" value="100"></div></div></div></figure><p>Now you have two options to continue:</p><ul><li>Modify existing form code</li><li>Add your own form code</li></ul><h3 id="option-1modify-existing-form-code">Option 1 - Modify existing form code</h3><p>Now we are going to override the default form processing URL with formcarry, to do that you are going to need your unique form endpoint URL that you grab in Step 1.</p><figure class="kg-card kg-video-card"><div class="kg-video-container"><video src="https://formcarry.com/blog/content/media/2022/12/editing_shopify_form_code.mp4" poster="https://img.spacergif.org/v1/1184x1080/0a/spacer.png" width="1184" height="1080" playsinline preload="metadata" style="background: transparent url(&apos;https://formcarry.com/blog/content/images/2022/12/media-thumbnail-ember442.jpg&apos;) 50% 50% / cover no-repeat;"></video><div class="kg-video-overlay"><button class="kg-video-large-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button></div><div class="kg-video-player-container"><div class="kg-video-player"><button class="kg-video-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button><button class="kg-video-pause-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"/><rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"/></svg></button><span class="kg-video-current-time">0:00</span><div class="kg-video-time">/<span class="kg-video-duration"></span></div><input type="range" class="kg-video-seek-slider" max="100" value="0"><button class="kg-video-playback-rate">1&#xD7;</button><button class="kg-video-unmute-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"/></svg></button><button class="kg-video-mute-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"/></svg></button><input type="range" class="kg-video-volume-slider" max="100" value="100"></div></div></div></figure><p><strong>Setting up form action:</strong></p><p>Find the following:</p><pre><code class="language-hbs">{%- form &apos;contact&apos;, id: &apos;ContactForm&apos;, class: &apos;isolate&apos; -%}</code></pre><p>And add action attribute with your unique endpoint URL like this:</p><pre><code class="language-hbs">{%- form &apos;contact&apos;, action: &apos;PASTE THE URL THAT YOU GOT IN STEP 1&apos;, id: &apos;ContactForm&apos;, class: &apos;isolate&apos; -%}</code></pre><blockquote>Make sure that you&#x2019;ve replaced PASTE THE URL THAT YOU GOT IN STEP 1, it should look like <a href="https://formcarry.com/s/XXXXXXX" rel="noopener noreferrer">https://formcarry.com/s/XXXXXXX</a>, if you don&#x2019;t replace that your form won&#x2019;t work.</blockquote><p><strong>Setting up field names:</strong></p><p>Now we need to give name to each field of your form, otherwise you&#x2019;ll lose the data of the field.</p><p>What you need is find every form field that has name attribute like this:</p><pre><code class="language-hbs">&lt;input name=&quot;contact[{{ &apos;templates.contact.form.name&apos; | t }}]&quot; ...</code></pre><p>And change the value between &#x201C;&#x201D; by giving your desired name so if the field is collecting legal name, just name it legalName:</p><pre><code class="language-hbs">&lt;input name=&quot;legalName&quot; ...</code></pre><p>Your form might not have the all possible fields but, here are the full list of possible fields that you have to name:</p><ul><li>Input</li><li>Select</li><li>Textarea</li></ul><blockquote>This part will require you to have basic HTML knowledge, but it&apos;s not difficult if you take a look around this awesome <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form">MDN document</a>. It shouldn&apos;t take you more than 2 minutes. If you want a more quick solution, you can use option 2, which is just copy/paste.</blockquote><h3 id="option-2add-your-own-form-code">Option 2 - Add your own form code </h3><p>If your store does not have a pre-made form, you can use our <a href="https://formcarry.com/contact-form">free contact form code generator</a>, which will give you a fully working contact form code without needing any further modifications. </p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-15.45.10.png" class="kg-image" alt="How to add a contact form to your Shopify website: Step-by-step guide" loading="lazy" width="1712" height="1403" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2022-12-27-at-15.45.10.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2022-12-27-at-15.45.10.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2022-12-27-at-15.45.10.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-15.45.10.png 1712w" sizes="(min-width: 720px) 720px"></figure><p>After you customized your form, click the code and copy your fully working code.</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-15.47.50.png" class="kg-image" alt="How to add a contact form to your Shopify website: Step-by-step guide" loading="lazy" width="1712" height="1403" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2022-12-27-at-15.47.50.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2022-12-27-at-15.47.50.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2022-12-27-at-15.47.50.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-15.47.50.png 1712w" sizes="(min-width: 720px) 720px"></figure><p>Now paste your code inside the page you want:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-15.51.09.png" class="kg-image" alt="How to add a contact form to your Shopify website: Step-by-step guide" loading="lazy" width="1712" height="1403" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2022-12-27-at-15.51.09.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2022-12-27-at-15.51.09.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2022-12-27-at-15.51.09.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-15.51.09.png 1712w" sizes="(min-width: 720px) 720px"></figure><p>Hooray &#x1F389; Now you have a working contact form!</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-15.51.55-1.png" class="kg-image" alt="How to add a contact form to your Shopify website: Step-by-step guide" loading="lazy" width="1712" height="1403" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2022-12-27-at-15.51.55-1.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2022-12-27-at-15.51.55-1.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2022-12-27-at-15.51.55-1.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-15.51.55-1.png 1712w" sizes="(min-width: 720px) 720px"></figure><p>It&#x2019;s time to add some magic to it.</p><h2 id="step-3testing-out-your-form">Step 3 - Testing out your form</h2><p>Just fill out your form with real data to test it (because formcarry has built-in spam filtering), you&#x2019;ll see that your forms is coming into the formcarry dashboard:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-16.00.34.png" class="kg-image" alt="How to add a contact form to your Shopify website: Step-by-step guide" loading="lazy" width="1712" height="1403" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2022-12-27-at-16.00.34.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2022-12-27-at-16.00.34.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2022-12-27-at-16.00.34.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-16.00.34.png 1712w" sizes="(min-width: 720px) 720px"></figure><h2 id="step-4setting-up-email-notifications-for-your-form">Step 4 - Setting up email notifications for your form</h2><p>We have a beautiful working form but it&#x2019;s not enough, let&#x2019;s add some spice to it, to set-up email notifications you&#x2019;ll have to go to Settings page inside your form, scroll down to the Self email notification, activate the integration, collapse down and add your desired emails to the notification list, like below:</p><figure class="kg-card kg-video-card"><div class="kg-video-container"><video src="https://formcarry.com/blog/content/media/2022/12/adding_email_notifications.mp4" poster="https://img.spacergif.org/v1/1270x1080/0a/spacer.png" width="1270" height="1080" playsinline preload="metadata" style="background: transparent url(&apos;https://formcarry.com/blog/content/images/2022/12/media-thumbnail-ember240.jpg&apos;) 50% 50% / cover no-repeat;"></video><div class="kg-video-overlay"><button class="kg-video-large-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button></div><div class="kg-video-player-container"><div class="kg-video-player"><button class="kg-video-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button><button class="kg-video-pause-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"/><rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"/></svg></button><span class="kg-video-current-time">0:00</span><div class="kg-video-time">/<span class="kg-video-duration"></span></div><input type="range" class="kg-video-seek-slider" max="100" value="0"><button class="kg-video-playback-rate">1&#xD7;</button><button class="kg-video-unmute-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"/></svg></button><button class="kg-video-mute-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"/></svg></button><input type="range" class="kg-video-volume-slider" max="100" value="100"></div></div></div></figure><p>Once you completed, submit your form again and you&#x2019;ll get the email notification instantly:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-16.07.00-1.png" class="kg-image" alt="How to add a contact form to your Shopify website: Step-by-step guide" loading="lazy" width="1712" height="1403" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2022-12-27-at-16.07.00-1.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2022-12-27-at-16.07.00-1.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2022-12-27-at-16.07.00-1.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-16.07.00-1.png 1712w" sizes="(min-width: 720px) 720px"></figure><p>If you don&#x2019;t got the email, it&#x2019;s possible that you filled out a test data and formcarry identified it as a spam, By default we don&#x2019;t send you email notifications if we mark a submission as spam to keep your inbox safe and sound. However, if you wish to disable this feature, you can do so by following the instructions in the screenshot provided below.</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-16.09.25.png" class="kg-image" alt="How to add a contact form to your Shopify website: Step-by-step guide" loading="lazy" width="1712" height="1403" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2022-12-27-at-16.09.25.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2022-12-27-at-16.09.25.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2022-12-27-at-16.09.25.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-16.09.25.png 1712w" sizes="(min-width: 720px) 720px"></figure><h2 id="step-5setting-up-auto-response-emails">Step 5 - Setting up auto response emails</h2><p>In most cases, the contact forms don&apos;t work and users don&apos;t get any response, so the best solution is to set up an auto-response email to let them know you have received their message and will reply to them shortly. Luckily it&#x2019;s really easy to set-up auto-responses with Formcarry.</p><p>To be able to set auto-responses the field that you collect user email must be named as <strong>&#x201C;email&#x201D;</strong> if you have used one of our templates then you don&#x2019;t need to worry about that, but if you have your own HTML form, then make sure that you modify it before setting-up this feature.</p><p>To setup, get into your form and navigate to your Settings, then scroll down to <em>Respondent Email Notification,</em> and enable the toggle.</p><p>After that click the pen icon on the right of the toggle and customize your template:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-18.41.41.png" class="kg-image" alt="How to add a contact form to your Shopify website: Step-by-step guide" loading="lazy" width="1901" height="1488" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2022-12-27-at-18.41.41.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2022-12-27-at-18.41.41.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2022-12-27-at-18.41.41.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2022-12-27-at-18.41.41.png 1901w" sizes="(min-width: 720px) 720px"></figure><p>Formcarry provides dynamic tags that can be embedded in your email templates. These tags can automatically populate the recipient&apos;s name and other details in the form. You can use those to send more personalized messages.</p><p>Once you are done with your template click save and now your form is ready to send auto-responses.</p><h2 id="going-further">Going further</h2><p>After covering all of these basics, it&#x2019;s also worth to mention that formcarry is an official Zapier partner</p><blockquote>Zapier is a tool for primarily non-technical users to connect together web apps. An integration between two apps is called a Zap. A Zap is made up of a Trigger and one or more Actions or Searches. Whenever the trigger happens in one app, Zapier will automatically perform the actions or searches in another app in order.</blockquote><p>Which means you can create complex marketing integrations with Formcarry using your form data, which is really powerful.</p><p>Some ideas for you to automate your form:</p><ul><li>Send data to Google Sheets every time a submission is received</li><li>Automatically export submissions to your CRM after each form is submitted</li><li>Create Google Calendar events for new leads or customers captured by your forms</li><li>Create Mailchimp campaigns for new leads or customers captured by your forms</li><li>Create Zendesk tickets to capture form data as a new ticket</li><li>Get SMS notifications when you get a new submissions using Twilio</li></ul><p>For more information about Zapier, I highly suggest watching this <a href="https://www.youtube.com/watch?v=FgLxncqDklo&amp;feature=youtu.be">video</a>.</p><h2 id="conclusion">Conclusion</h2><p>Thank you for taking your time to read this article, I hope it will help you set up your contact form on your website.</p>]]></content:encoded></item><item><title><![CDATA[How to create a simple HTML contact form from scratch]]></title><description><![CDATA[In this guide you'll learn how to create a HTML contact form that sends you an email by bare minimum code with PHP and CSS or with formcarry]]></description><link>https://formcarry.com/blog/how-to-create-a-simple-html-contact-form/</link><guid isPermaLink="false">635d10de491e327b5902846c</guid><category><![CDATA[Guides]]></category><dc:creator><![CDATA[Nusu Alabuga]]></dc:creator><pubDate>Mon, 31 Oct 2022 04:54:30 GMT</pubDate><media:content url="https://formcarry.com/blog/content/images/2022/10/Cover.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://formcarry.com/blog/content/images/2022/10/Cover.jpg" alt="How to create a simple HTML contact form from scratch"><p>In this guide I&#x2019;m going to show you <strong>how to create a HTML contact form that sends you an email</strong> by bare minimum code.</p><p>Collecting form submissions is an essential part of any business. There are drag-and-drop form builders, but sometimes you might want to use just your HTML form. Let&apos;s get started!</p><p>You can scroll down to see <strong><a href="#create-a-form-using-html">HTML code for contact form&#x1F447;</a></strong> on front-end, followed by the PHP code for <strong><a href="#option-1-html-form-processing-with-php">processing form data&#x1F447;</a></strong> that delivers your form to email.</p><h2 id="table-of-contents-">Table of contents:</h2><hr><ul><li><a href="#create-a-form-using-html">HTML Form Code</a></li><li><a href="#css-codes-for-your-html-form">CSS Style Code</a></li><li>Form Processing Code</li><li><a href="#option-1-html-form-processing-with-php">Option 1: Form processing with PHP</a></li><li><a href="#option-2-html-form-processing-with-formcarry">Option 2: Form processing using Form Backend</a></li><li><a href="#html-label-field">HTML Label Field</a></li><li><a href="#html-text-field">HTML Text Field</a></li><li><a href="#html-textarea-field">HTML Textarea Field</a></li><li><a href="#html-email-field">HTML Email Field</a></li><li><a href="#html-telephone-field">HTML Telephone Field</a></li><li><a href="#html-date-field">HTML Date Field</a></li><li><a href="#html-password-field">HTML Password Field</a></li></ul><p>The form we&#x2019;re building is very simple, if you want to achieve advanced features like file upload or spam protection please take a look at our <strong><a href="https://formcarry.com/blog/how-to-create-a-html-contact-form-with-file-upload/">file upload form &#x2197;&#xFE0F;</a></strong></p><blockquote>Already have a HTML form and not much time? We offer spam protection, google sheets integration, and email notifications for free at <strong><a href="https://formcarry.com">formcarry &#x2197;&#xFE0F;</a></strong></blockquote><hr><h2 id="create-a-simple-html-contact-form">Create a Simple HTML Contact Form</h2><p>Copy and paste this code to your HTML page, this is going to be the base of our form.</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot; /&gt;
    &lt;title&gt;Contact Form&lt;/title&gt;
    &lt;!-- Form styling --&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;formcarry-form.css&quot; /&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;formcarry-container&quot;&gt;
      &lt;form action=&quot;#&quot; method=&quot;POST&quot; class=&quot;formcarry-form&quot;&gt;
        &lt;label for=&quot;name&quot;&gt;Your Name&lt;/label&gt;
        &lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;fullName&quot; required /&gt;

        &lt;label for=&quot;email&quot;&gt;Your Email Address&lt;/label&gt;
        &lt;input type=&quot;email&quot; id=&quot;email&quot; name=&quot;email&quot; required /&gt;

        &lt;label for=&quot;message&quot;&gt;Your Message&lt;/label&gt;
        &lt;textarea name=&quot;message&quot; id=&quot;message&quot; cols=&quot;30&quot; rows=&quot;10&quot;&gt;&lt;/textarea&gt;

        &lt;button type=&quot;submit&quot;&gt;Send&lt;/button&gt;
      &lt;/form&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><figcaption>How do you make a web form from scratch?</figcaption></figure><hr><h2 id="css-codes-for-your-html-form">CSS codes for your HTML form</h2><p><strong>File name: formcarry-form.css</strong> (Please save using exact name)</p><p>Paste this code to make styling work</p><pre><code class="language-css">@import url(&quot;https://fonts.googleapis.com/css2?family=Inter:wght@400;700&amp;display=swap&quot;);

/* 
  CONTACT FORM EXAMPLE FOR FORMCARRY

  IMPORTANT NOTE:
  PLEASE ADD formcarry-form class to your form element
  to apply the styles.
*/

.formcarry-container * {
  box-sizing: border-box;
	font-family: &quot;Inter&quot;, sans-serif;

  /* colors */
  --color-blue: #2552d0;
  --color-light-blue: #3266e3;
  --color-gray: #e5e7eb;
  --color-dark-gray: #9da3ae;
  --color-pink: #edadd2;
}

.formcarry-container {
  /* container */
  --c-width: 50%;
  --c-max-width: 500px;

  width: var(--c-width);
  max-width: var(--c-max-width);
  display: block;
  margin: 10vh auto 0 auto;
}

.formcarry-form label {
  display: block;
  padding: 12px 0 2px 0;
  letter-spacing: -0.2px;
  cursor: pointer;
  font-size: 16px;
  font-weight: 700;
}

.formcarry-form input,
.formcarry-form textarea {
  font-size: 16px;
  display: block;
  width: 100%;
  padding: 10px;
  background-color: var(--color-gray);
  border: none;
  border: 4px solid var(--color-gray);
  outline: none;
  border-radius: 8px;
  color: var(--color-dark-gray);
}

.formcarry-form input:focus,
.formcarry-form textarea:focus {
  background-color: #fff;
  color: var(--color-dark-gray);
}

.formcarry-form input:focus:required:invalid {
  border-color: var(--color-pink);
  background-color: #fff;
}

.formcarry-form button {
  display: block;
  margin-top: 12px;
  width: 100%;
  padding: 12px 20px;
  border-radius: 8px;
	border-color: transparent;
  background-color: var(--color-blue);
  color: #fff;
  font-weight: 700;
  font-size: 18px;

  transition: 300ms all;
}

.formcarry-form button:hover {
  background-color: var(--color-light-blue);
}

.formcarry-alert {
  padding: 12px;
  border-radius: 10px;
  color: #fff;
  font-size: 14px;
  font-weight: 400;
  margin-top: 12px;
  display: none;
}

.formcarry-alert.visible {
  display: block;
}

.formcarry-alert.success {
  background: #69cf9d;
}

.formcarry-alert.error {
  background: #de524c;
}</code></pre><h2 id="bonus-free-html5-contact-form-generator">Bonus: Free HTML5 Contact Form Generator</h2><p>We have created a form generator that you can use to build your own contact forms and completely customize it with your brand or website&apos;s color scheme and design style. They are free to download and can be used on your personal or commercial projects. </p><p>Click here to check out our <a href="https://formcarry.com/html-form-generator">free form generator &#x2197;&#xFE0F;</a></p><hr><h2 id="option-1-html-form-processing-with-php">Option 1: HTML Form Processing with PHP</h2><p>First replace the <code>#</code> with <code>form-process.php</code> like below</p><pre><code class="language-html">&lt;!-- Replace this --&gt;
&lt;form action=&quot;#&quot; method=&quot;POST&quot; class=&quot;formcarry-form&quot;&gt;
&lt;!-- With this --&gt;
&lt;form action=&quot;form-process.php&quot; method=&quot;POST&quot; class=&quot;formcarry-form&quot;&gt;</code></pre><blockquote>Why? because action part of the form element tells your browser to where to send form data, in this case we need to point our form data to<strong> form-process.php</strong></blockquote><p>Then create a file called: <strong>form-process.php</strong> (should be exact name)</p><pre><code class="language-php">&lt;?php
if (isset($_POST[&apos;email&apos;])) {

    // REPLACE THIS 2 LINES AS YOU DESIRE
    $email_to = &quot;you@awesomecompany.com&quot;;
    $email_subject = &quot;You&apos;ve got a new submission&quot;;

    function problem($error)
    {
        echo &quot;Oh looks like there is some problem with your form data: &lt;br&gt;&lt;br&gt;&quot;;
        echo $error . &quot;&lt;br&gt;&lt;br&gt;&quot;;
        echo &quot;Please fix those to proceed.&lt;br&gt;&lt;br&gt;&quot;;
        die();
    }

    // validation expected data exists
    if (
        !isset($_POST[&apos;fullName&apos;]) ||
        !isset($_POST[&apos;email&apos;]) ||
        !isset($_POST[&apos;message&apos;])
    ) {
        problem(&apos;Oh looks like there is some problem with your form data.&apos;);
    }

    $name = $_POST[&apos;fullName&apos;]; // required
    $email = $_POST[&apos;email&apos;]; // required
    $message = $_POST[&apos;message&apos;]; // required

    $error_message = &quot;&quot;;
    $email_exp = &apos;/^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/&apos;;

    if (!preg_match($email_exp, $email)) {
        $error_message .= &apos;Email address does not seem valid.&lt;br&gt;&apos;;
    }

    $string_exp = &quot;/^[A-Za-z .&apos;-]+$/&quot;;

    if (!preg_match($string_exp, $name)) {
        $error_message .= &apos;Name does not seem valid.&lt;br&gt;&apos;;
    }

    if (strlen($message) &lt; 2) {
        $error_message .= &apos;Message should not be less than 2 characters&lt;br&gt;&apos;;
    }

    if (strlen($error_message) &gt; 0) {
        problem($error_message);
    }

    $email_message = &quot;Form details following:\n\n&quot;;

    function clean_string($string)
    {
        $bad = array(&quot;content-type&quot;, &quot;bcc:&quot;, &quot;to:&quot;, &quot;cc:&quot;, &quot;href&quot;);
        return str_replace($bad, &quot;&quot;, $string);
    }

    $email_message .= &quot;Name: &quot; . clean_string($name) . &quot;\n&quot;;
    $email_message .= &quot;Email: &quot; . clean_string($email) . &quot;\n&quot;;
    $email_message .= &quot;Message: &quot; . clean_string($message) . &quot;\n&quot;;

    // create email headers
    $headers = &apos;From: &apos; . $email . &quot;\r\n&quot; .
        &apos;Reply-To: &apos; . $email . &quot;\r\n&quot; .
        &apos;X-Mailer: PHP/&apos; . phpversion();
    @mail($email_to, $email_subject, $email_message, $headers);
?&gt;

    &lt;!-- Replace this as your success message --&gt;

    Thanks for contacting us, we will get back to you as soon as possible.

&lt;?php
}
?&gt;</code></pre><p>This is how your form supposed to look like:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/form-html.png" class="kg-image" alt="How to create a simple HTML contact form from scratch" loading="lazy" width="1024" height="1114" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/form-html.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/form-html.png 1000w, https://formcarry.com/blog/content/images/2022/10/form-html.png 1024w" sizes="(min-width: 720px) 720px"></figure><p>While this will create a working HTML form that sends you an email, you need to be aware of:</p><ul><li><strong>No spam protection:</strong> spam submissions can be 90% of the total submissions if there is no protection in-built which takes time to implement and improve.</li><li><strong>Emails can land into the spam folder:</strong> you need to check your SMTP server health regularly, your server might crash and you won&#x2019;t notice it for a long time, which can cost very bad for your business.</li><li><strong>File upload takes time to implement:</strong> In case you need to upload files from your form, be aware that implementation of it takes a lot of time, and creates a lot more complexity and security concerns to deal with.</li></ul><hr><h2 id="option-2-html-form-processing-with-formcarry">Option 2: HTML form processing with Formcarry</h2><p>If you need more functionalities from your form, you need to deal with the complexity that comes with it. If you want to make a working simple HTML contact <a href="https://formcarry.com">form backend</a> without PHP, we have the solution.</p><p>Try our product <a href="https://formcarry.com">formcarry &#x2197;&#xFE0F;</a> for free which can be a perfect solution for you, it works with your own HTML code, you just need to change your form action attribute.</p><h3 id="create-a-form-in-formcarry">Create a form in formcarry</h3><p><a href="https://app.formcarry.com/register">Create an account &#x2197;&#xFE0F;</a> then create a form like below</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://formcarry.com/blog/content/images/2022/10/create-form.gif" class="kg-image" alt="How to create a simple HTML contact form from scratch" loading="lazy" width="1970" height="1439" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/create-form.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/create-form.gif 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/create-form.gif 1600w, https://formcarry.com/blog/content/images/2022/10/create-form.gif 1970w" sizes="(min-width: 720px) 720px"><figcaption>Create a form in formcarry</figcaption></figure><h3 id="integrate-your-html-form">Integrate your HTML form</h3><p>Copy your form endpoint by clicking <strong>copy clipboard</strong> button, then change your HTML form code that we used above.</p><pre><code class="language-html">&lt;!-- Replace this --&gt;
&lt;form action=&quot;#&quot; method=&quot;POST&quot; class=&quot;formcarry-form&quot;&gt;
&lt;!-- With this --&gt;
&lt;form action=&quot;{PASTE YOUR FORM ENDPOINT HERE}&quot; method=&quot;POST&quot; class=&quot;formcarry-form&quot;&gt;
</code></pre><p>That&#x2019;s all you need to process your form now</p><h3 id="try-your-form">Try your form</h3><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/CleanShot-2022-10-23-at-22.15.49.gif" class="kg-image" alt="How to create a simple HTML contact form from scratch" loading="lazy" width="1970" height="1439" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/CleanShot-2022-10-23-at-22.15.49.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/CleanShot-2022-10-23-at-22.15.49.gif 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/CleanShot-2022-10-23-at-22.15.49.gif 1600w, https://formcarry.com/blog/content/images/2022/10/CleanShot-2022-10-23-at-22.15.49.gif 1970w" sizes="(min-width: 720px) 720px"></figure><p>Just by changing your action attribute, you can achieve:</p><ul><li><a href="https://formcarry.com/docs/features/thank-you-pages">3 different thank you page</a> &#x2197;&#xFE0F; for your form.</li><li><a href="https://formcarry.com/docs/features/self-email-notifications">Email notifications &#x2197;&#xFE0F;</a> for new submissions</li><li><a href="https://formcarry.com/docs/features/respondent-email-notifications">Auto-responses &#x2197;&#xFE0F;</a> for your submitters</li><li>A dashboard that you can sort, filter and export your form data</li><li><a href="https://formcarry.com/blog/how-to-create-a-file-upload-form/">Easy file uploads &#x2197;&#xFE0F;</a></li><li><a href="https://formcarry.com/docs/integrations/zapier">Integrations with Google Sheets and 1000+ other apps &#x2197;&#xFE0F;</a></li></ul><p>Take a look at your dashboard and you&#x2019;ll see your new submission:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/read-submission.gif" class="kg-image" alt="How to create a simple HTML contact form from scratch" loading="lazy" width="1970" height="1440" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/read-submission.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/read-submission.gif 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/read-submission.gif 1600w, https://formcarry.com/blog/content/images/2022/10/read-submission.gif 1970w" sizes="(min-width: 720px) 720px"></figure><p>Also email notification for the new submission, which you can add as many emails as you like from the self email notification settings.</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/email-client.png" class="kg-image" alt="How to create a simple HTML contact form from scratch" loading="lazy" width="2000" height="1744" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/email-client.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/email-client.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/email-client.png 1600w, https://formcarry.com/blog/content/images/size/w2400/2022/10/email-client.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Creating a working form with formcarry less than 2 minutes, and it&#x2019;s free up to 100 submissions per month.</p><hr><h2 id="html-form-field-examples">HTML Form Field examples</h2><p>It&apos;s possible for you to ask which HTML element is used to create an HTML form for user input? Let us show you the fields that you can use in your form, just copy and paste the codes below.</p><hr><h3 id="html-label-field">HTML Label Field</h3><p>Label field is the text that&#x2019;ll focus to the desired form element on click, to target a field you need to give target element id inside the label elements for attribute like this:</p><pre><code class="language-html">&lt;!-- insert the ID of target element inside the for attribute --&gt;
&lt;label for=&quot;myElement&quot;&gt;Focus to the field&lt;/label&gt;
&lt;!-- give an ID attribute to the target element so label can work --&gt;
&lt;input id=&quot;myElement&quot; type=&quot;text&quot; /&gt;
</code></pre><!--kg-card-begin: html--><style>
.formcarry-container * {
  box-sizing: border-box;

  /* colors */
  --color-blue: #2552d0;
  --color-light-blue: #3266e3;
  --color-gray: #e5e7eb;
  --color-dark-gray: #9da3ae;
  --color-pink: #edadd2;
  font-family: "Inter", sans-serif;
}

.formcarry-container {
  /* container */
  --c-width: 50%;
  --c-max-width: 500px;

  width: var(--c-width);
  max-width: var(--c-max-width);
  display: block;
  margin: 20px auto 0 auto;
}

.formcarry-form label {
  display: block;
  padding: 12px 0 2px 0;
  letter-spacing: -0.2px;
  cursor: pointer;
  font-size: 16px;
  font-weight: 700;
}

.formcarry-form input,
.formcarry-form textarea {
  font-size: 16px;
  display: block;
  width: 100%;
  padding: 10px;
  background-color: var(--color-gray);
  border: none;
  border: 4px solid var(--color-gray);
  outline: none;
  border-radius: 8px;
  color: var(--color-dark-gray);
}

.formcarry-form input:focus,
.formcarry-form textarea:focus {
  background-color: #fff;
  color: var(--color-dark-gray);
}

.formcarry-form input:focus:required:invalid {
  border-color: var(--color-pink);
  background-color: #fff;
}

.formcarry-form button {
  display: block;
  margin-top: 12px;
  width: 100%;
  padding: 12px 20px;
  border-radius: 8px;
  background-color: var(--color-blue);
  border-color: transparent;
  color: #fff;
  font-weight: 700;
  font-size: 18px;

  transition: 300ms all;
}

.formcarry-form button:hover {
  background-color: var(--color-light-blue);
}

.formcarry-alert {
  padding: 12px;
  border-radius: 10px;
  color: #fff;
  font-size: 14px;
  font-weight: 400;
  margin-top: 12px;
  display: none;
}

.formcarry-alert.visible {
  display: block;
}

.formcarry-alert.success {
  background: #69cf9d;
}

.formcarry-alert.error {
  background: #de524c;
}
</style>
<div class="formcarry-container">
    <form action="#" method="POST" class="formcarry-form">
        <label for="name">Focus to the field</label>
        <input type="text" id="name" name="fullName" required>
    </form>
</div>
<!--kg-card-end: html--><hr><h3 id="html-text-field">HTML Text Field</h3><p>Text field is the most used form field on the web, this is widely used for short texts.</p><pre><code class="language-html">&lt;label for=&quot;name&quot;&gt;Text Field&lt;/label&gt;
&lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;fullName&quot; /&gt;
</code></pre><!--kg-card-begin: html--><div class="formcarry-container">
    <form action="#" method="POST" class="formcarry-form">
        <label for="name">Text Field</label>
        <input type="text" id="name" name="fullName">
    </form>
</div><!--kg-card-end: html--><hr><h3 id="html-textarea-field">HTML Textarea Field</h3><p>Textarea is like text field but it&#x2019;s for much bigger content, like messages.</p><pre><code class="language-html">&lt;label for=&quot;message&quot;&gt;Textarea Field&lt;/label&gt;
&lt;textarea type=&quot;text&quot; id=&quot;message&quot; rows=&quot;5&quot; cols=&quot;5&quot; name=&quot;message&quot;&gt;&lt;/textarea&gt;
</code></pre><p><code>rows</code> and <code>cols</code> attributes allow you to specify width and height of textarea yet you can always manipulate that using CSS.</p><!--kg-card-begin: html--><div class="formcarry-container">
    <form action="#" method="POST" class="formcarry-form">
        <label for="message">Textarea Field</label>
        <textarea type="text" id="message" name="message" rows="5" cols="30"></textarea>
    </form>
</div><!--kg-card-end: html--><h3 id="html-email-field">HTML Email Field</h3><p>Some HTML fields have built in validations, Email input is one of them, it will complain unless you enter a valid email address, and it won&#x2019;t let you submit.</p><pre><code class="language-html">&lt;input type=&quot;email&quot; /&gt;
</code></pre><!--kg-card-begin: html--><div class="formcarry-container">
    <form action="#" method="POST" class="formcarry-form">
        <label for="message">Email Field</label>
        <input type="email" id="email" name="emailAddress" required>
        <button type="submit">Send</button>
    </form>
</div><!--kg-card-end: html--><blockquote>Try to submit by entering normal text, the field will warn you that it requires a valid email address</blockquote><blockquote>Notice how input border color reacts to validity of your input, until you enter a valid email address you&#x2019;ll see a red color, I&#x2019;ve implemented this for demo purposes so that&#x2019;s not the default behavior.</blockquote><hr><h3 id="html-telephone-field">HTML Telephone Field</h3><p>You specify a number pattern with telephone field, and it will complain unless you enter phone number through the pattern you have specified.</p><pre><code class="language-html">&lt;input type=&quot;tel&quot; pattern=&quot;[0-9]{3}-[0-9]{2}-[0-9]{3}&quot; /&gt;
</code></pre><!--kg-card-begin: html--><div class="formcarry-container">
      <form action="#" method="POST" class="formcarry-form">
        <label for="telephone">Telephone Field</label>
        <input type="tel" id="telephone" name="telephone" pattern="[0-9]{3}-[0-9]{2}-[0-9]{3}" required>
        <p>Required format 123-45-678</p>
        <button type="submit">Send</button>
      </form>
    </div><!--kg-card-end: html--><p>Tel field also shows num pad on mobile devices.</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/telephone-1.png" class="kg-image" alt="How to create a simple HTML contact form from scratch" loading="lazy" width="390" height="844"></figure><hr><h3 id="html-date-field">HTML Date Field</h3><p>Date field is very handy most of the time, because it&#x2019;s a native type all devices will show some sort of date selector to the user, you can specify minimum and maximum ranges for dates to be chosen.</p><pre><code class="language-html">&lt;input type=&quot;date&quot; value=&quot;2022-10-29&quot; min=&quot;2022-01-01&quot; max=&quot;2022-12-31&quot; /&gt;
</code></pre><!--kg-card-begin: html--><div class="formcarry-container">
      <form action="#" method="POST" class="formcarry-form">
        <label for="date">Date Field</label>
        <input type="date" id="date" name="date" value="2022-10-29" min="2022-01-01" max="2022-12-31">
        <button type="submit">Send</button>
      </form>
    </div><!--kg-card-end: html--><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/date.png" class="kg-image" alt="How to create a simple HTML contact form from scratch" loading="lazy" width="390" height="844"></figure><hr><h3 id="html-password-field">HTML Password Field</h3><p>Password field is normal text field but the difference is the value you entered will be masked with asterisks to hide sensitive information.</p><pre><code class="language-html">&lt;input type=&quot;password&quot; /&gt;
</code></pre><!--kg-card-begin: html--><div class="formcarry-container">
    <form action="#" method="POST" class="formcarry-form">
        <label for="pw">Password Field</label>
        <input type="password" id="pw" name="pw">
    </form>
</div><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[How to upload files from your HTML form using Base64 encoding]]></title><description><![CDATA[Learn how to quickly encode your file input content as Base64 Data URI and save it to your server]]></description><link>https://formcarry.com/blog/how-to-upload-files-as-base64/</link><guid isPermaLink="false">61431d1c5963bf293706f28c</guid><category><![CDATA[Guides]]></category><dc:creator><![CDATA[Nusu Alabuga]]></dc:creator><pubDate>Thu, 16 Sep 2021 11:16:04 GMT</pubDate><media:content url="https://formcarry.com/blog/content/images/2021/09/cvr-4---8-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://formcarry.com/blog/content/images/2021/09/cvr-4---8-1.png" alt="How to upload files from your HTML form using Base64 encoding"><p>Uploading files using Base64 encoding is a common practice, the usage of the technique has been increased since React and Vue.js like frameworks gained popularity.</p><p>In this guide I&apos;m going to show you how to upload files using base64 encoding</p><h2 id="what-s-base64-encoding">What&apos;s Base64 Encoding?</h2><blockquote>Base64 is a encoding <a href="https://base64.guru/learn/base64-algorithm">algorithm</a> that allows you to transform any characters into an alphabet which consists of Latin letters, digits, plus, and slash. You can convert images into a &#x201C;readable&#x201D; string, which can be saved or transferred anywhere.</blockquote><p>To understand it better I recommend you to take a look at that wonderful article from <a href="https://base64.guru/learn/what-is-base64">base64.guru</a> and <a href="https://levelup.gitconnected.com/what-is-base64-encoding-4b5ed1eb58a4">What is Base64 Encoding</a> by Akshay Kumar</p><h2 id="what-s-data-uri">What&apos;s Data URI?</h2><p>We can&apos;t just send the Base64 string to our server and process it, what makes it different than any other string? How do you know the file is a image or PDF file? That&apos;s where Data URI comes in.</p><p>Data URI or Data URL is a format that we can use some data as an inline string. In order to process our Base64 data in server we need to know the mime type (which can be tricked), which Data URI format provides this.</p><p>This is the Data URI or Data URL format:</p><pre><code class="language-bash">data:[&lt;mime type&gt;][;charset=&lt;charset&gt;][;base64],&lt;encoded data&gt;
</code></pre><p>For example this a Base64 string wrapped as a Data URI:</p><pre><code class="language-jsx">&lt;img src=&quot;data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoHCBUWFRgVFRYZGRgZHBgYGBwYGhgYGBoYGBgaGhoZGBgcIS4lHB4rIRgYJjgmKy8xNTU1GiQ7QDs0Py40NTEBDAwMEA8QHBISGjQh...3000 more characters&quot; /&gt;
</code></pre><p>The output:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://formcarry.com/blog/content/images/2021/09/uncle-ben.jpg" class="kg-image" alt="How to upload files from your HTML form using Base64 encoding" loading="lazy" width="259" height="194"><figcaption>Uncle Ben after Base64</figcaption></figure><h2 id="live-demo">Live demo</h2><p>Try it yourself! Choose a file and see base64 encoding of it.</p><!--kg-card-begin: html--><style>
.formcarryContainer {
  width: var(--c-width);
  max-width: var(--c-max-width);
  display: block;
  margin: 20px auto 0 auto;
  box-sizing: border-box;
  font-family: "Inter", sans-serif;


  /* colors */
  --color-blue: #2552d0;
  --color-light-blue: #3266e3;
  --color-gray: #e5e7eb;
  --color-dark-gray: #9da3ae;
  --color-pink: #edadd2;

  /* container */
  --c-width: 50%;
  --c-max-width: 500px;
}

#formcarryForm label {
  display: block;
  padding: 12px 0 2px 0;
  letter-spacing: -0.2px;
  cursor: pointer;
  font-size: 16px;
  font-weight: 700;
}

#formcarryForm input,
#formcarryForm textarea {
  font-size: 16px;
  display: block;
  width: 100%;
  padding: 10px;
  background-color: var(--color-gray);
  border: none;
  border: 4px solid var(--color-gray);
  outline: none;
  border-radius: 8px;
  color: var(--color-dark-gray);
}

#formcarryForm input:focus,
#formcarryForm textarea:focus {
  background-color: #fff;
  color: var(--color-dark-gray);
}

#formcarryForm input:focus:required:invalid {
  border-color: var(--color-pink);
  background-color: #fff;
}

#formcarryForm button {
  display: block;
  margin-top: 12px;
  width: 100%;
  padding: 12px 20px;
  border-radius: 8px;
  background-color: var(--color-blue);
  color: #fff;
  font-weight: 700;
  font-size: 18px;

  transition: 300ms all;
}

#formcarryForm button:hover {
  background-color: var(--color-light-blue);
}

.formcarry-alert {
  padding: 12px;
  border-radius: 10px;
  color: #fff;
  font-size: 14px;
  font-weight: 400;
  margin-top: 12px;
  display: none;
}

.formcarry-alert.visible {
  display: block;
}

.formcarry-alert.success {
  background: #69cf9d;
}

.formcarry-alert.error {
  background: #de524c;
}

.powered-by,
.data-holder {
  width: var(--c-width);
  max-width: var(--c-max-width);
  margin: 0 auto;
}

.powered-by p {
  text-align: right;
  font-size: 11px;
  color: #838da0;
  padding-top: 5px;
}

.powered-by a {
  font-weight: 800;
  text-decoration: underline;
}
    
.data-holder {
    margin-top: 20px;
}

.data-holder pre {
  min-width: 350px;
  max-width: 350px;
  max-height: 400px;
  white-space: inherit;
  overflow: scroll;
}
</style>
<div class="formcarryContainer">
      <form id="formcarryForm">
        <label for="pictureInput">Picture</label>
        <input type="file" id="pictureInput" name="picture" multiple>
      </form>
    </div>

    <div class="data-holder">
      <p>DATA (choose a file to see):</p>
      <pre id="code"></pre>
    </div>

    <script>
      // demo purposes only
      const codeElem = document.getElementById("code");
      // /demo purposes only

      const fileInput = document.getElementById("pictureInput");

      // This is for storing the base64 strings
      let myFiles = {};
      // if you expect files by default, make this disabled
      // we will wait until the last file being processed
      let isFilesReady = true;

      fileInput.addEventListener("change", async (event) => {
        // clean up earliest items
        myFiles = {};
        // set state of files to false until each of them is processed
        isFilesReady = false;

        // this is to get the input name attribute, in our case it will yield as "picture"
        // I'm doing this because I want you to use this code dynamically
        // so if you change the input name, the result also going to effect
        const inputKey = fileInput.getAttribute("name");
        var files = event.srcElement.files;

        const filePromises = Object.entries(files).map((item) => {
          return new Promise((resolve, reject) => {
            const [index, file] = item;
            const reader = new FileReader();
            reader.readAsBinaryString(file);

            reader.onload = function (event) {
              // if it's multiple upload field then set the object key as picture[0], picture[1]
              // otherwise just use picture
              const fileKey = `${inputKey}${
                files.length > 1 ? `[${index}]` : ""
              }`;
              // Convert Base64 to data URI
              // Assign it to your object
              myFiles[fileKey] = `data:${file.type};base64,${btoa(
                event.target.result
              )}`;

              resolve();
            };
            reader.onerror = function () {
              console.log("can't read the file");
              reject();
            };
          });
        });

        Promise.all(filePromises)
          .then(() => {
            console.log("ready to submit");
            isFilesReady = true;

            // demo purposes only
            codeElem.textContent = JSON.stringify(myFiles, undefined, 2);
            // /demo purposes only
          })
          .catch((error) => {
            console.log(error);
            console.log("something wrong happened");
          });
      });

      const formElement = document.getElementById("formcarryForm");

      const handleForm = async (event) => {
        event.preventDefault();

        if (!isFilesReady) {
          console.log("files still getting processed");
          return;
        }

        const formData = new FormData(formElement);

        let data = {
          name: formData.get("name"),
          message: formData.get("message")
        };

        Object.entries(myFiles).map((item) => {
          const [key, file] = item;
          // append the file to data object
          data[key] = file;
        });

        // demo purposes only
        codeElem.textContent = JSON.stringify(data, undefined, 2);
        // /demo purposes only

        alert("submit is disabled for this example.");
        // fetch("https://formcarry.com/s/{Your-Unique-Endpoint}", {
        //   method: "POST",
        //   body: JSON.stringify(data),
        //   headers: {
        //     "Content-Type": "application/json",
        //     Accept: "application/json"
        //   }
        // })
        //   // convert response to json
        //   .then((r) => r.json())
        //   .then((res) => {
        //     console.log(res);
        //   });
      };

      formElement.addEventListener("submit", handleForm);
    </script><!--kg-card-end: html--><p>Wanna play with it? Use our <a href="https://codesandbox.io/s/formcarry-base64-example-d6uxi">CodeSandbox Example</a></p><h2 id="create-your-html-form">Create your HTML Form</h2><p>Let&apos;s create a very simple form, we are going to handle it with Javascript</p><pre><code class="language-html">&lt;form id=&quot;formcarryForm&quot;&gt;
 	&lt;label for=&quot;nameInput&quot;&gt;Name&lt;/label&gt;
 	&lt;input type=&quot;text&quot; id=&quot;nameInput&quot; /&gt;

	&lt;label for=&quot;messageInput&quot;&gt;Message&lt;/label&gt;
 	&lt;textarea id=&quot;messageInput&quot; cols=&quot;30&quot; rows=&quot;2&quot;&gt;&lt;/textarea&gt;

	&lt;input type=&quot;file&quot; id=&quot;pictureInput&quot; /&gt;

  	&lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;
</code></pre><p><strong>Update 6 Jan, 2023:</strong></p><p>We have built <a href="https://formcarry.com/html-form-generator">free form generator</a> tool that you can customize and get HTML code, make sure you check it out if you need form template.</p><h2 id="add-your-javascript-code">Add your Javascript code</h2><p>In order to upload files as Base64, we need to listen the change event of our file input, and the process is async so we need to hold some state to determinate whether we can submit the form or not.</p><p>Let&apos;s start with our file input.</p><pre><code class="language-javascript">const fileInput = document.getElementById(&apos;pictureInput&apos;)

// This is for storing the base64 strings
let myFiles = {}
// if you expect files by default, make this disabled
// we will wait until the last file being processed
let isFilesReady = true

fileInput.addEventListener(&apos;change&apos;, async (event) =&gt; {
  const files = event.srcElement.files;

  console.log(files)
})
</code></pre><p>We are going to use <code>isFilesReady</code> later to check if the async process has been completed or not, it&apos;s true by default because there are no files in the input when the page loads, if you want to make it required you can change it to <code>isFilesReady = false</code></p><p>Let&apos;s try what happens:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2021/09/CleanShot-2021-07-10-at-12.23.47.gif" class="kg-image" alt="How to upload files from your HTML form using Base64 encoding" loading="lazy" width="1032" height="720" srcset="https://formcarry.com/blog/content/images/size/w600/2021/09/CleanShot-2021-07-10-at-12.23.47.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2021/09/CleanShot-2021-07-10-at-12.23.47.gif 1000w, https://formcarry.com/blog/content/images/2021/09/CleanShot-2021-07-10-at-12.23.47.gif 1032w" sizes="(min-width: 720px) 720px"></figure><p>As you can see, we can access our files, now it&apos;s time for the fun part.</p><h2 id="converting-input-file-to-base64-string">Converting input file to base64 string</h2><p>We are going to use native FileReader API to read files from the input</p><pre><code class="language-javascript">fileInput.addEventListener(&apos;change&apos;, async (event) =&gt; {
  // clean up earliest items
  myFiles = {}
  // set state of files to false until each of them is processed
  isFilesReady = false

  const files = event.srcElement.files;

  const filePromises = Object.entries(files).map(item =&gt; {
    return new Promise((resolve, reject) =&gt; {
      const [index, file] = item
      const reader = new FileReader();
      reader.readAsBinaryString(file);

      reader.onload = function(event) {
        // handle reader success

        resolve()
      };

      reader.onerror = function() {
        console.log(&quot;couldn&apos;t read the file&quot;);
        reject()
      };
    })
  })

  Promise.all(filePromises)
    .then(() =&gt; {
      // if each file processed successfuly then set our state to true
      isFilesReady = true
    })
    .catch((error) =&gt; {
      console.log(error)
      console.log(&apos;something wrong happened&apos;)
    })
})
</code></pre><p>Now we can access FileReader data using <code>event.target.result</code> but we need to transform it to Base64 string, let&apos;s do that:</p><pre><code class="language-javascript">fileInput.addEventListener(&apos;change&apos;, async (event) =&gt; {
  // clean up earliest files
  myFiles = {}
  // set state of files to false until each of them is processed
  isFilesReady = false

  const files = event.srcElement.files;

  const filePromises = Object.entries(files).map(item =&gt; {
    return new Promise((resolve, reject) =&gt; {
      const [index, file] = item
      const reader = new FileReader();
      reader.readAsBinaryString(file);

      reader.onload = function(event) {
        // Convert file to Base64 string
		// btoa is built int javascript function for base64 encoding
        myFiles[&apos;picture&apos;] = btoa(event.target.result)

        resolve()
      };
      reader.onerror = function() {
        console.log(&quot;can&apos;t read the file&quot;);
        reject()
      };
    })
  })

  Promise.all(filePromises)
    .then(() =&gt; {
      console.log(&apos;ready to submit&apos;)
      isFilesReady = true
    })
    .catch((error) =&gt; {
      console.log(error)
      console.log(&apos;something wrong happened&apos;)
    })
})
</code></pre><p>So now we have converted our file to Base64 string and pushed it inside the <code>myFiles</code> object. every time our input get changes, <code>myFiles</code> is going to erase all the data it holds and will process everything again.</p><h2 id="converting-files-to-data-uri">Converting files to Data URI</h2><p>We have converted our files to Base64 string but that&apos;s not enough to upload files, we need to convert it to <strong>Data URI</strong>, it should look like this;</p><pre><code class="language-jsx">data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoHCBUWFRgVFRYZGRgZHBgYGBwYGhgYGBoYGBgaGhoZGBgcIS4lHB4rIRgYJjgmKy8xNTU1GiQ7QDs0Py40NTEBDAwMEA8QHBISGjQh...3000 more characters</code></pre><p>The format is;</p><pre><code class="language-jsx">data:[&lt;mime type&gt;][;charset=&lt;charset&gt;][;base64],&lt;encoded data&gt;
</code></pre><p>Fortunately, we can access the MimeType, so that&apos;s going to be easy like that:</p><pre><code class="language-jsx">// Convert Base64 to data URI
// Assign it to your object
myFiles[&apos;picture&apos;] = `data:${file.type};base64,${btoa(event.target.result)}`
</code></pre><p>So now it&apos;s ready to upload. But let&apos;s make some tweaks before we go on.</p><p>I have named our file input as picture for the example, let&apos;s make our code dynamic so it can get the file input name attribute</p><pre><code class="language-javascript">// this is to get the input name attribute, in our case it will yield as &quot;picture&quot;
// I&apos;m doing this because I want you to use this code dynamically
// so if you change the input name, the result also going to effect
const inputKey = fileInput.getAttribute(&apos;name&apos;)
</code></pre><p>then change this;</p><pre><code class="language-javascript">myFiles[inputKey] = `data:${file.type};base64,${btoa(event.target.result)}`
</code></pre><p>that way if you change your input name to <code>resume</code> it will yield as <code>myFiles[&apos;resume&apos;]</code></p><h2 id="converting-multiple-files-to-base64-at-once">Converting multiple files to base64 at once</h2><p>Let&apos;s cover our code so it can support multiple file input;</p><pre><code class="language-javascript">&lt;input type=&quot;file&quot; id=&quot;pictureInput&quot; multiple/&gt;
</code></pre><p>So in that case, we want to check if input has single or multiple files, if it has single file we want to name it right according to input name, in our example it would be <code>picture</code> but if it has more than one file, we are going to name with file lengths such as <code>picture[0]</code>, <code>picture[1]</code></p><p>here&apos;s the code:</p><pre><code class="language-diff">+ // if it&apos;s multiple upload field then set the object key as picture[0], picture[1]
+ // otherwise just use picture
+ const fileKey = `${inputKey}${files.length &gt; 1 ? `[${index}]` : &apos;&apos;}`
+ // Convert Base64 to data URI
+ // Assign it to your object
- myFiles[inputKey] = `data:${file.type};base64,${btoa(event.target.result)}`
+ myFiles[fileKey] = `data:${file.type};base64,${btoa(event.target.result)}`
</code></pre><h2 id="handle-the-form-submit-event">Handle the form submit event</h2><p>Let&apos;s cover our form submit event, what we want to do in that case is we will check if the files are ready, if they&apos;re not we are going to show an alert to user</p><pre><code class="language-javascript">const formElement = document.getElementById(&apos;formcarryForm&apos;)

const handleForm = async (event) =&gt; {
  event.preventDefault();

  if(!isFilesReady){
    alert(&apos;files still getting processed&apos;)
  }
}

formElement.addEventListener(&apos;submit&apos;, handleForm)
</code></pre><p>All of the code we wrote so far should look like this;</p><pre><code class="language-javascript">const fileInput = document.getElementById(&apos;pictureInput&apos;)

// This is for storing the base64 strings
let myFiles = {}
// if you expect files by default, make this disabled
// we will wait until the last file being processed
let isFilesReady = true

fileInput.addEventListener(&apos;change&apos;, async (event) =&gt; {
  // clean up earliest items
  myFiles = {}
  // set state of files to false until each of them is processed
  isFilesReady = false

  // this is to get the input name attribute, in our case it will yield as &quot;picture&quot;
  // I&apos;m doing this because I want you to use this code dynamically
  // so if you change the input name, the result also going to effect
  const inputKey = fileInput.getAttribute(&apos;name&apos;)
  var files = event.srcElement.files;

  const filePromises = Object.entries(files).map(item =&gt; {
    return new Promise((resolve, reject) =&gt; {
      const [index, file] = item
      const reader = new FileReader();
      reader.readAsBinaryString(file);

      reader.onload = function(event) {
        // if it&apos;s multiple upload field then set the object key as picture[0], picture[1]
        // otherwise just use picture
        const fileKey = `${inputKey}${files.length &gt; 1 ? `[${index}]` : &apos;&apos;}`
        // Convert Base64 to data URI
        // Assign it to your object
        myFiles[fileKey] = `data:${file.type};base64,${btoa(event.target.result)}`

        resolve()
      };
      reader.onerror = function() {
        console.log(&quot;can&apos;t read the file&quot;);
        reject()
      };
    })
  })

  Promise.all(filePromises)
    .then(() =&gt; {
      console.log(&apos;ready to submit&apos;)
      isFilesReady = true
    })
    .catch((error) =&gt; {
      console.log(error)
      console.log(&apos;something wrong happened&apos;)
    })
})

const formElement = document.getElementById(&apos;formcarryForm&apos;)

const handleForm = async (event) =&gt; {
  event.preventDefault();

  if(!isFilesReady){
    console.log(&apos;files still getting processed&apos;)
	return
  }
}

formElement.addEventListener(&apos;submit&apos;, handleForm)
</code></pre><p>Let&apos;s create an object of our form values in the form submit event;</p><pre><code class="language-javascript">const formElement = document.getElementById(&apos;formcarryForm&apos;)

const handleForm = async (event) =&gt; {
  event.preventDefault();

  if(!isFilesReady){
    console.log(&apos;files still getting processed&apos;)
    return
  }
 
  const formData = new FormData(formElement)

	// get name and message input from our &lt;form&gt; element
  let data = {
    &apos;name&apos;: formData.get(&apos;name&apos;),
    &apos;message&apos;: formData.get(&apos;message&apos;)
  }

	// iterate over the base64 files we&apos;ve converted
  Object.entries(myFiles).map(item =&gt; {
	// destruct the file
    const [key, file] = item
	// append it to our data object
    data[key] = file
  })

  console.log(data)
}

formElement.addEventListener(&apos;submit&apos;, handleForm)
</code></pre><p>Let&apos;s try it out:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2021/09/CleanShot-2021-07-10-at-13.26.39.gif" class="kg-image" alt="How to upload files from your HTML form using Base64 encoding" loading="lazy" width="1020" height="720" srcset="https://formcarry.com/blog/content/images/size/w600/2021/09/CleanShot-2021-07-10-at-13.26.39.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2021/09/CleanShot-2021-07-10-at-13.26.39.gif 1000w, https://formcarry.com/blog/content/images/2021/09/CleanShot-2021-07-10-at-13.26.39.gif 1020w" sizes="(min-width: 720px) 720px"></figure><h2 id="what-s-next">What&apos;s next?</h2><p>We&apos;ve done all the necessary stuff on the front-end except network request part.</p><p>At <a href="https://formcarry.com">formcarry</a> we allow our customers to upload files as Base64 (pro feature).</p><p>You can either use our service to handle your form, or you can write a server code to process Base64 Data URI.</p><p>Luckily for you, I&apos;m going to cover both of them.</p><h2 id="1-1-uploading-base64-to-formcarry">1.1- Uploading Base64 to <a href="https://formcarry.com">formcarry</a></h2><p>Now we can send our data to formcarry, the important thing in this step is converting our object to JSON and setting the Content Type as application/json.</p><pre><code class="language-javascript">const handleForm = async (event) =&gt; {
  event.preventDefault();

  if(!isFilesReady){
    console.log(&apos;files still getting processed&apos;)
    return
  }
 
  const formData = new FormData(formElement)

  let data = {
    &apos;name&apos;: formData.get(&apos;name&apos;),
    &apos;message&apos;: formData.get(&apos;message&apos;)
  }

  Object.entries(myFiles).map(item =&gt; {
    const [key, file] = item
	// append the file to data object
    data[key] = file
  })

  fetch(&apos;https://formcarry.com/s/{Your-Unique-Endpoint}&apos;, {
    method: &apos;POST&apos;,
    body: JSON.stringify(data),
    headers: {
      &apos;Content-Type&apos;: &apos;application/json&apos;,
      Accept: &apos;application/json&apos;
    }
  })
  // convert response to json
  .then(r =&gt; r.json())
  .then(res =&gt; {
    console.log(res);
  });
}
</code></pre><p>Change &#xA0;<code>https://formcarry.com/s/{Your-Unique-Endpoint}</code> with your unique form ID</p><h2 id="1-2-try-it-out">1.2- Try it out</h2><p>Submit your form by filling out all of the fields, then refresh your dashboard</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2021/09/CleanShot-2021-07-07-at-17.28.12@2x.png" class="kg-image" alt="How to upload files from your HTML form using Base64 encoding" loading="lazy" width="2000" height="1768" srcset="https://formcarry.com/blog/content/images/size/w600/2021/09/CleanShot-2021-07-07-at-17.28.12@2x.png 600w, https://formcarry.com/blog/content/images/size/w1000/2021/09/CleanShot-2021-07-07-at-17.28.12@2x.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2021/09/CleanShot-2021-07-07-at-17.28.12@2x.png 1600w, https://formcarry.com/blog/content/images/2021/09/CleanShot-2021-07-07-at-17.28.12@2x.png 2384w" sizes="(min-width: 720px) 720px"></figure><p>Formcarry will automagically convert your base64 to download-ready file.</p><h2 id="2-uploading-base64-to-nodejs">2- Uploading Base64 to NodeJS</h2><p>I&apos;m going to use Express.js for our example, let&apos;s create an express app using express-generator</p><pre><code class="language-bash">$ npx express-generator 
</code></pre><p>Approximately Base64 files are 33% heavier than the original file, you might want to keep that in mind.</p><p>Now, let&apos;s allow our server to process large body data by getting into the <code>app.js</code> and change:</p><pre><code class="language-diff">-app.use(express.json());
-app.use(express.urlencoded({ extended: false }));
+app.use(express.json({limit: &apos;50mb&apos;}));
+app.use(express.urlencoded({ extended: true, limit: &apos;50mb&apos; }));
</code></pre><p>Also we need to enable CORS to perform request from our front-end app:</p><pre><code class="language-bash">npm i --save cors
</code></pre><p>Enable it like this:</p><pre><code class="language-javascript">var express = require(&apos;express&apos;);
var ba64 = require(&apos;ba64&apos;);
var cors = require(&apos;cors&apos;);

var app = express();

app.use(cors());
</code></pre><p>I&apos;m going to remove all the unnecessary stuff, you can replace this with your app.js:</p><pre><code class="language-javascript">var createError = require(&apos;http-errors&apos;);
var express = require(&apos;express&apos;);
var path = require(&apos;path&apos;);
var cors = require(&apos;cors&apos;)

var app = express();

app.use(cors());

app.use(express.json({limit: &apos;50mb&apos;}));
app.use(express.urlencoded({ extended: true, limit: &apos;50mb&apos; }));
app.use(express.static(path.join(__dirname, &apos;public&apos;)));

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get(&apos;env&apos;) === &apos;development&apos; ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render(&apos;error&apos;);
});

module.exports = app;
</code></pre><h2 id="2-1-creating-our-process-route">2.1- Creating our process route</h2><p>Now we need to create a Express route to process our form data.</p><p>But first we are going to use a tiny package called <code>ba64</code> which will help us to save base64 images to our disk.</p><p>The flow should be like this;</p><ul><li>Check the key is a valid Data URI</li><li>If it&apos;s valid extract the Base64 string from Data URI</li><li>Extract the mimetype from Data URI</li><li>Save to the disk</li></ul><p>That&apos;s where <code>ba64</code> package comes in, it will automatically extract Base64 string from Data URI, and append the file extension after the file name automatically.</p><pre><code class="language-bash">npm i --save ba64
</code></pre><p>Import it in our <code>app.js</code></p><pre><code class="language-javascript">var ba64 = require(&apos;ba64&apos;)
</code></pre><p>Let&apos;s create our route, go to <code>app.js</code> and add following:</p><pre><code class="language-javascript">app.post(&apos;/upload&apos;, async (req, res, next) =&gt; {
  // exclude name and message for the sake of demo
  // all other body items will be considered as a file
  const { name, message, ...files } = req.body

  for(let key in files){
    const base64 = files[key]

    // check if it&apos;s correctly formatted Base64 Data URI
    if(checkBase64(base64)){
      // Write it to our root directory using input key as filename
      // eg. picture[1]
      ba64.writeImageSync(key, base64)
    }
  }

  res.send({files})
})

function checkBase64(string){
  const B64_REGEX = /^data:.*;base64,([0-9a-zA-Z+\\/]{4})*(([0-9a-zA-Z+\\/]{2}==)|([0-9a-zA-Z+\\/]{3}=))?$/i 

  return B64_REGEX.test(string)
}
</code></pre><p>Final code should look like:</p><pre><code class="language-javascript">var createError = require(&apos;http-errors&apos;);
var express = require(&apos;express&apos;);
var path = require(&apos;path&apos;);
var ba64 = require(&apos;ba64&apos;)
var cors = require(&apos;cors&apos;)

var app = express();

app.use(cors());

// view engine setup
app.use(express.json({limit: &apos;50mb&apos;}));
app.use(express.urlencoded({ extended: true, limit: &apos;50mb&apos; }));
app.use(express.static(path.join(__dirname, &apos;public&apos;)));


app.post(&apos;/upload&apos;, async (req, res, next) =&gt; {
  // exclude name and message for the sake of demo
  // all other body items will be considered as a file
  const { name, message, ...files } = req.body

  for(let key in files){
    const base64 = files[key]

    // check if it&apos;s correctly formatted Base64 Data URI
    if(checkBase64(base64)){
      // Write it to our root directory using input key as filename
      // eg. picture[1]
      ba64.writeImageSync(key, base64)
    }
  }

  res.send({files})
})

function checkBase64(string){
  const B64_REGEX = /^data:.*;base64,([0-9a-zA-Z+\/]{4})*(([0-9a-zA-Z+\/]{2}==)|([0-9a-zA-Z+\/]{3}=))?$/i 

  return B64_REGEX.test(string)
}

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get(&apos;env&apos;) === &apos;development&apos; ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render(&apos;error&apos;);
});

module.exports = app;
</code></pre><p>Now run the app using:</p><pre><code class="language-bash">$ npm start
</code></pre><h2 id="2-2-configure-front-end">2.2 - Configure Front-end</h2><p>Let&apos;s get back to our front-end code and point our form to the back-end our server runs at <code>http://localhost:3000</code> and our route is <code>localhost:3000/upload</code></p><pre><code class="language-javascript">const handleForm = async (event) =&gt; {
  event.preventDefault();

  if(!isFilesReady){
    console.log(&apos;files still getting processed&apos;)
    return
  }
 
  const formData = new FormData(formElement)

  let data = {
    &apos;name&apos;: formData.get(&apos;name&apos;),
    &apos;message&apos;: formData.get(&apos;message&apos;)
  }

  Object.entries(myFiles).map(item =&gt; {
    const [key, file] = item
	// append the file to data object
    data[key] = file
  })

  fetch(&apos;http://localhost:3000/upload&apos;, {
    method: &apos;POST&apos;,
    body: JSON.stringify(data),
    headers: {
      &apos;Content-Type&apos;: &apos;application/json&apos;,
      Accept: &apos;application/json&apos;
    }
  })
  // convert response to json
  .then(r =&gt; r.json())
  .then(res =&gt; {
    console.log(res);
  });
}
</code></pre><p>Let&apos;s try it:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2021/09/CleanShot-2021-09-16-at-13.27.04.gif" class="kg-image" alt="How to upload files from your HTML form using Base64 encoding" loading="lazy" width="1198" height="594" srcset="https://formcarry.com/blog/content/images/size/w600/2021/09/CleanShot-2021-09-16-at-13.27.04.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2021/09/CleanShot-2021-09-16-at-13.27.04.gif 1000w, https://formcarry.com/blog/content/images/2021/09/CleanShot-2021-09-16-at-13.27.04.gif 1198w" sizes="(min-width: 720px) 720px"></figure><p>It works!</p><h2 id="conclusion">Conclusion</h2><p>Thanks for following the blog post to the end, base64 is a tricky issue that&apos;s why I wanted to prepare an end-to-end fully functional tutorial.</p><p>I hope it&apos;s beneficial for you, if you have any questions just leave a comment and I&apos;ll try my best.</p><p>If you want to support us, just take a look at our service <a href="https://formcarry.com">formcarry</a> for a hassle free form handling.</p>]]></content:encoded></item><item><title><![CDATA[How to create a file upload form with formcarry in 5 steps]]></title><description><![CDATA[Learn how to create a file upload ready HTML form in 5 steps, super simple!]]></description><link>https://formcarry.com/blog/how-to-create-a-file-upload-form/</link><guid isPermaLink="false">60e9a76e5963bf293706f1b1</guid><category><![CDATA[Guides]]></category><dc:creator><![CDATA[Nusu Alabuga]]></dc:creator><pubDate>Mon, 12 Jul 2021 07:19:43 GMT</pubDate><media:content url="https://formcarry.com/blog/content/images/2021/07/file-upload-form.png" medium="image"/><content:encoded><![CDATA[<img src="https://formcarry.com/blog/content/images/2021/07/file-upload-form.png" alt="How to create a file upload form with formcarry in 5 steps"><p>One of the most time consuming thing about forms is definitely uploading files, sometimes you may need an HTML form with file upload functionality, in this guide we are going to start by as simple as possible than we are going to jump to advanced techniques</p><h2 id="after-you-read-this-guide">After you read this guide</h2><ul><li>You can create a file upload form in <strong>5 steps,</strong> <strong>under 3 minutes</strong></li><li>You can get email notifications from your HTML form</li><li>You can export your contact form submissions as CSV and JSON</li><li>You don&apos;t have to deal with any back end code stuff (Php, Go, Node.js etc.)</li></ul><h2 id="step-1-create-your-html-form">Step 1 &#x2014; Create your HTML Form</h2><p>First, you&apos;ll need an HTML form in your web page, which is not a big deal, a basic HTML upload form will look like this.</p><pre><code class="language-html">&lt;form action=&quot;#&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
	&lt;label for=&quot;nameInput&quot;&gt;Name&lt;/label&gt;
	&lt;input type=&quot;text&quot; id=&quot;nameInput&quot; /&gt;

	&lt;label for=&quot;messageInput&quot;&gt;Message&lt;/label&gt;
	&lt;textarea id=&quot;messageInput&quot; cols=&quot;30&quot; rows=&quot;2&quot;&gt;&lt;/textarea&gt;

	&lt;input type=&quot;file&quot; id=&quot;pictureInput&quot; /&gt;

	&lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;
</code></pre><blockquote>Your form element have to include <code>enctype=&quot;multipart/form-data&quot;</code> to upload files</blockquote><blockquote>A basic form in HTML is just a static thing that&apos;s only obligated to deliver the user input to a <a href="https://www.conceptatech.com/blog/difference-front-end-back-end-development">back-end</a> script. You have to point the form to some script to actually process the data.</blockquote><p>if you want to have a fully styled form you can use our <a href="https://formcarry.com/templates">free form generator</a> tool to generate a customized form code.</p><p>By default, file input only allows you to choose a single file from your device, if you want it to allow multiple files then you can use the <code>multiple</code> attribute</p><pre><code class="language-html">&lt;input type=&quot;file&quot; id=&quot;pictureInput&quot; multiple /&gt;
</code></pre><h2 id="step-2-structure-your-form-data">Step 2 &#x2014; Structure your form data</h2><p>In order to send your form data to a script you need to name each of your fields so the script can match the values with the names (or the key).</p><p>You can add as many fields as you want.</p><p>Let&apos;s uniquely name each of our fields using <code>name</code> attribution.</p><pre><code class="language-jsx">&lt;form action=&quot;#&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
	&lt;label for=&quot;nameInput&quot;&gt;Name&lt;/label&gt;
  	&lt;input type=&quot;text&quot; id=&quot;nameInput&quot; name=&quot;name&quot; /&gt;

	&lt;label for=&quot;messageInput&quot;&gt;Message&lt;/label&gt;
	&lt;textarea id=&quot;messageInput&quot; cols=&quot;30&quot; rows=&quot;2&quot; name=&quot;message&quot;&gt;&lt;/textarea&gt;

	&lt;label for=&quot;pictureInput&quot;&gt;Picture&lt;/label&gt;
	&lt;input type=&quot;file&quot; id=&quot;pictureInput&quot; name=&quot;picture&quot; /&gt;

	&lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;
</code></pre><p>Now we have a file upload form that&apos;s ready to deliver the data to a script.</p><h2 id="step-3-point-your-form-to-backend">Step 3 &#x2014; Point your form to backend</h2><p>There are two ways to handle this step, this part is the most time consuming stuff due to you have to check files, rename them uniquely save to database and upload to somewhere along with you&apos;ll also probably going to need a email server to send emails, which you always have to make sure that emails are delivered.</p><h3 id="option-1-create-your-own-form-back-end">Option 1 &#x2014; Create your own form back-end</h3><p>You need to have a <a href="https://formcarry.com">form backend</a> to collect submissions and files from your form, this is typically done by some backend languages such as PHP, Node.js, Go etc.</p><p>We have a detailed guide on <a href="https://formcarry.com/blog/how-to-create-a-html-contact-form-with-file-upload/">How to create a form backend with file upload</a></p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://formcarry.com/blog/how-to-create-a-html-contact-form-with-file-upload/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">How to create an HTML contact form with file upload | Actionable Guide</div><div class="kg-bookmark-description">In this tutorial, we are going to create a sample app using Express.js to uploadfiles to Amazon S3, then we are going to save our submission to the MongoDB Prerequisites for the tutorialI don&#x2019;t want to cover some things that would over-complicate this tutorial,therefore I assume you know how to:&#x2026;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://formcarry.com/blog/favicon.png" alt="How to create a file upload form with formcarry in 5 steps"><span class="kg-bookmark-author">Formcarry Blog</span><span class="kg-bookmark-publisher">Nusu Alabuga</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://formcarry.com/blog/content/images/2020/10/cvr-1-2.png" alt="How to create a file upload form with formcarry in 5 steps"></div></a></figure><p>Take a look at that post if you want to build it on your own</p><h3 id="option-2-use-formcarry-file-upload-ready-form-backend">Option 2 &#x2014; Use Formcarry - File upload ready form backend</h3><p>Formcarry is a free, <a href="https://formcarry.com">no-code form backend for your HTML forms</a>, in this tutorial I&apos;m going to show you how can you create a file upload form under 3 minutes while it at least takes 1 hours if you do it on your own. Also you can get notification emails from your form, protected from spam by default and integrate your submission data with other apps using <a href="https://zapier.com">Zapier</a>.</p><p><a href="https://formcarry.com/register"><strong>Sign Up</strong></a> to formcarry for free, then click <strong><a href="https://formcarry.com/profile/add-form">Add New</a></strong> to get your unique form backend URL</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2021/07/create-form-1.gif" class="kg-image" alt="How to create a file upload form with formcarry in 5 steps" loading="lazy" width="1200" height="820" srcset="https://formcarry.com/blog/content/images/size/w600/2021/07/create-form-1.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2021/07/create-form-1.gif 1000w, https://formcarry.com/blog/content/images/2021/07/create-form-1.gif 1200w" sizes="(min-width: 720px) 720px"></figure><p>Then copy your unique form endpoint</p><h2 id="step-4-integrate-your-form-with-formcarry">Step 4 &#x2014; Integrate your form with formcarry</h2><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2021/07/CleanShot-2021-06-29-at-11.31.05@2x.png" class="kg-image" alt="How to create a file upload form with formcarry in 5 steps" loading="lazy" width="2000" height="1527" srcset="https://formcarry.com/blog/content/images/size/w600/2021/07/CleanShot-2021-06-29-at-11.31.05@2x.png 600w, https://formcarry.com/blog/content/images/size/w1000/2021/07/CleanShot-2021-06-29-at-11.31.05@2x.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2021/07/CleanShot-2021-06-29-at-11.31.05@2x.png 1600w, https://formcarry.com/blog/content/images/size/w2400/2021/07/CleanShot-2021-06-29-at-11.31.05@2x.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Copy your endpoint and paste it into <code>action</code> part of your form</p><pre><code class="language-diff">- &lt;form action=&quot;#&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
+ &lt;form action=&quot;https://formcarry.com/s/{Your-Unique-Endpoint}&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
</code></pre><h2 id="step-5-collect-submissions">Step 5 &#x2014; Collect submissions</h2><p>Let&apos;s try out our form:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2021/07/CleanShot-2021-07-07-at-17.17.01.gif" class="kg-image" alt="How to create a file upload form with formcarry in 5 steps" loading="lazy" width="800" height="703" srcset="https://formcarry.com/blog/content/images/size/w600/2021/07/CleanShot-2021-07-07-at-17.17.01.gif 600w, https://formcarry.com/blog/content/images/2021/07/CleanShot-2021-07-07-at-17.17.01.gif 800w" sizes="(min-width: 720px) 720px"></figure><p>Now, let&apos;s take a look at our dashboard:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2021/07/CleanShot-2021-07-07-at-17.26.00-1.gif" class="kg-image" alt="How to create a file upload form with formcarry in 5 steps" loading="lazy" width="2000" height="1730" srcset="https://formcarry.com/blog/content/images/size/w600/2021/07/CleanShot-2021-07-07-at-17.26.00-1.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2021/07/CleanShot-2021-07-07-at-17.26.00-1.gif 1000w, https://formcarry.com/blog/content/images/size/w1600/2021/07/CleanShot-2021-07-07-at-17.26.00-1.gif 1600w, https://formcarry.com/blog/content/images/2021/07/CleanShot-2021-07-07-at-17.26.00-1.gif 2250w" sizes="(min-width: 720px) 720px"></figure><p>That&apos;s all you need to upload files when you are using formcarry, that&apos;s how deadly simple it is. We have covered the basics, now let&apos;s jump into something a little bit advanced.</p><hr><h2 id="uploading-files-from-your-form-using-javascript">Uploading files from your form using Javascript</h2><p>Uploading files with raw HTML form is not so time consuming, but if you are trying to upload it with javascript it&apos;s possible that you are going to spend some time on figuring out what&apos;s going wrong.</p><p>First add our form <code>id=&quot;formcarryForm&quot;</code></p><pre><code class="language-diff">- &lt;form action=&quot;https://formcarry.com/s/{Your-Unique-Endpoint}&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
+ &lt;form id=&quot;formcarryForm&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
</code></pre><h3 id="important-note-before-we-switch-back-to-code">Important note before we switch back to code</h3><p>Common mistake while implementing a file upload in javascript is setting <code>Content-Type</code> as <code>multipart/form-data</code> while this is partly true, it&apos;s also very wrong approach.</p><p>Any content-type starts with <code>multipart/*</code> is required to have boundary, based on my own experiences and the support request we got from formcarry, we found out the ideal way to upload files from javascript is using the FormData class</p><pre><code class="language-javascript">const formElement = document.getElementById(&apos;formcarryForm&apos;)

const data = new FormData(formElement)
</code></pre><p>this will get each field from your form, but if you want to add some additional data, that you don&apos;t want to store in the HTML, you can add your additional data like that;</p><pre><code class="language-javascript">const formElement = document.getElementById(&apos;formcarryForm&apos;)

const data = new FormData(formElement)

data.append(&apos;language&apos;, window.navigator.language)
</code></pre><h3 id="uploading-files-from-your-form-using-fetch-api">Uploading files from your form using Fetch API</h3><p>Fetch API is an embedded request API for javascript, it&apos;s widely supported among modern browsers, <a href="https://caniuse.com/fetch">check Fetch API compability</a>.</p><p>Add this script before the <code>&lt;/body&gt;</code> tag</p><pre><code class="language-html">&lt;script&gt;
  const formcarryForm = document.getElementById(&apos;formcarryForm&apos;)

  const sendFormData = async (event) =&gt; {
    // this will prevent your form to redirect to another page.
    event.preventDefault();
		
    // get our form data
    const formData = new FormData(formcarryForm)
    // add some additional data if you want
    // formData.append(&apos;language&apos;, window.navigator.language)

    fetch(&apos;https://formcarry.com/s/{Your-Unique-Endpoint}&apos;, {
      method: &apos;POST&apos;,
      body: formData,
      headers: {
		// you don&apos;t have to set Content-Type
		// otherwise it won&apos;t work due to boundary!
        Accept: &apos;application/json&apos;
      }
    })
    // convert response to json
    .then(r =&gt; r.json())
    .then(res =&gt; {
      console.log(res);
    });
  }

  // Bind our sendFormData function to our forms submit event
  formcarryForm.addEventListener(&apos;submit&apos;, sendFormData);
&lt;/script&gt;
</code></pre><h3 id="uploading-files-from-your-form-using-axios">Uploading files from your form using Axios</h3><p>Axios is an promise based HTTP client for the browser and node.js, it&apos;s lightweight and a common library for making HTTP requests, it&apos;s a nice alternative for Fetch API</p><p>Add this script before the <code>&lt;/body&gt;</code> tag</p><pre><code class="language-html">&lt;script&gt;
  const formcarryForm = document.getElementById(&apos;formcarryForm&apos;)

  const sendFormData = async (event) =&gt; {
    // this will prevent your form to redirect to another page.
    event.preventDefault();
		
	// get our form data
	const formData = new FormData(formcarryForm);
	// add some additional data if you want
	// formData.append(&apos;language&apos;, window.navigator.language)

    axios
      .post(&quot;https://formcarry.com/s/{Your-Unique-Endpoint}&quot;, formData, {
        headers: { 
			// you don&apos;t have to set Content-Type
			// otherwise it won&apos;t work due to boundary!
			Accept: &quot;application/json&quot; 
		},
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        // this is an error related to request
        console.log(error);
      });
  };

  // Bind our sendFormData function to our forms submit event
  formcarryForm.addEventListener(&apos;submit&apos;, sendFormData);
&lt;/script&gt;
</code></pre><h3 id="uploading-files-from-your-form-with-react">Uploading Files from your form with React</h3><p>Using <code>FormData</code> class in React is a little bit tweaky, but let&apos;s take a look how to upload files with React.</p><p>We need to use <code>useRef</code> to access our form element, here&apos;s a sample component for you to upload files with React:</p><pre><code class="language-jsx">import React, { useRef } from &quot;react&quot;

const Form = () =&gt; {
  // create a Ref to access our form element
  const formRef = useRef(null)

  const sendFormData = async (event) =&gt; {
    // this will prevent your form to redirect to another page.
    event.preventDefault();

    if(!formRef.current){
      console.log(&apos;something wrong with form ref&apos;)
      return
    }
		
    // get our form data
    const formData = new FormData(formRef.current)

    // add some additional data if you want
    // formData.append(&apos;language&apos;, window.navigator.language)

    fetch(&apos;https://formcarry.com/s/{Your-Unique-Endpoint}&apos;, {
      method: &apos;POST&apos;,
      body: formData,
      headers: {
		// you don&apos;t have to set Content-Type
		// otherwise it won&apos;t work due to boundary!
        Accept: &apos;application/json&apos;
      }
    })
    // convert response to json
    .then(r =&gt; r.json())
    .then(res =&gt; {
      console.log(res);
    });
  }

  return (
	// bind formRef to our form element
    &lt;form ref={formRef} onSubmit={sendFormData}&gt;
      &lt;label htmlFor=&quot;nameInput&quot;&gt;Name&lt;/label&gt;
      &lt;input type=&quot;text&quot; id=&quot;nameInput&quot; name=&quot;name&quot; /&gt;

      &lt;label htmlFor=&quot;messageInput&quot;&gt;Message&lt;/label&gt;
      &lt;textarea id=&quot;messageInput&quot; name=&quot;message&quot;&gt;&lt;/textarea&gt;

      &lt;label htmlFor=&quot;pictureInput&quot;&gt;Picture&lt;/label&gt;
      &lt;input type=&quot;file&quot; id=&quot;pictureInput&quot; name=&quot;picture&quot; /&gt;

      &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
    &lt;/form&gt;
  )
}

export default Form
</code></pre><p>That&apos;s all! here&apos;s the live demo: <a href="https://codesandbox.io/s/file-upload-6ox4w?from-embed=&amp;file=/index.html">codesandbox</a></p><hr><h2 id="conclusion">Conclusion</h2><p>I hope this guide was helpful for you, at formcarry our mission is providing an easy way to handle your HTML forms also we are trying to release form related in-depth guides, make sure you&apos;ve subscribed our newsletter to get the latest posts.</p>]]></content:encoded></item><item><title><![CDATA[How to create a working contact form with HTML]]></title><description><![CDATA[Learn how to create a contact form and collect form submissions from your HTML form in 4 steps and under 3 minutes + Free form templates]]></description><link>https://formcarry.com/blog/how-to-create-a-contact-form/</link><guid isPermaLink="false">60daddb85963bf293706f0cc</guid><category><![CDATA[Guides]]></category><dc:creator><![CDATA[Nusu Alabuga]]></dc:creator><pubDate>Mon, 05 Jul 2021 07:42:00 GMT</pubDate><media:content url="https://formcarry.com/blog/content/images/2022/12/cvr-33-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://formcarry.com/blog/content/images/2022/12/cvr-33-1.png" alt="How to create a working contact form with HTML"><p><a href="https://formcarry.com/contact-form-generator">Contact forms</a> are one of the best ways to convert more leads, and get the information you need from your visitors in a specific order, but usually it&apos;s not so easy to craft, in this guide we are going to make it easy like a cake!</p><p>Sometimes you may want to create a <a href="https://formcarry.com">contact form without PHP</a>, if that&apos;s the case, this tutorial might be really helpful to you.</p><h2 id="after-you-read-this-guide">After you read this guide</h2><ul><li>You can create a working HTML contact form in <strong>4 steps,</strong> <strong>under 3 minutes</strong> for free</li><li>You&apos;ll have a predefined CSS for you to quickly start</li><li>You can <a href="https://formcarry.com">get email notifications from your contact form</a></li><li>You can export your contact form submissions as CSV and JSON</li><li>You don&apos;t have to deal with any back end code stuff (Php, Go, Node.js etc.)</li></ul><h2 id="step-1-create-your-html-form-and-css">Step 1 &#x2014; Create your HTML Form and CSS</h2><p>First, you&apos;ll need an HTML form in your web page, which is not a big deal, a basic HTML contact form will look like this.</p><pre><code class="language-html">&lt;form class=&quot;formcarryForm&quot; action=&quot;#&quot; method=&quot;POST&quot;&gt;
  &lt;label for=&quot;firstNameInput&quot;&gt;First Name&lt;/label&gt;
  &lt;input type=&quot;text&quot; id=&quot;firstNameInput&quot; /&gt;

  &lt;label for=&quot;lastNameInput&quot;&gt;Last Name&lt;/label&gt;
  &lt;input type=&quot;text&quot; id=&quot;lastNameInput&quot; /&gt;

  &lt;label for=&quot;emailInput&quot;&gt;Email&lt;/label&gt;
  &lt;input type=&quot;email&quot; id=&quot;emailInput&quot; /&gt;

  &lt;label for=&quot;messageInput&quot;&gt;Message&lt;/label&gt;
  &lt;textarea id=&quot;messageInput&quot; cols=&quot;30&quot; rows=&quot;10&quot;&gt;&lt;/textarea&gt;

  &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;
</code></pre><blockquote>A basic form in HTML is just a static thing that&apos;s only obligated to deliver the user input to a <a href="https://www.conceptatech.com/blog/difference-front-end-back-end-development">back-end</a> script. You have to point the form to some script to actually process the data.</blockquote><p>I have created a sample design for the sake of our blog post, which you can use it in your website for free.</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/12/CleanShot-2021-06-29-at-11.22.24@2x.png" class="kg-image" alt="How to create a working contact form with HTML" loading="lazy" width="2000" height="1847" srcset="https://formcarry.com/blog/content/images/size/w600/2022/12/CleanShot-2021-06-29-at-11.22.24@2x.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/12/CleanShot-2021-06-29-at-11.22.24@2x.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/12/CleanShot-2021-06-29-at-11.22.24@2x.png 1600w, https://formcarry.com/blog/content/images/2022/12/CleanShot-2021-06-29-at-11.22.24@2x.png 2150w" sizes="(min-width: 720px) 720px"></figure><p>Here&apos;s the CSS code that you can copy and use:</p><pre><code class="language-html">&lt;style&gt;
    @import url(&quot;https://fonts.googleapis.com/css2?family=Inter:wght@400;700&amp;display=swap&quot;);

    /* 
    CONTACT FORM EXAMPLE FOR FORMCARRY

    IMPORTANT NOTE:
    PLEASE ADD formcarryForm class to your form element
    to apply the styles.
    */

    * {
        box-sizing: border-box;

        /* colors */
        --color-blue: #2552d0;
        --color-light-blue: #3266e3;
        --color-gray: #e5e7eb;
        --color-dark-gray: #9da3ae;
        --color-pink: #edadd2;

        /* container */
        --c-width: 50%;
        --c-max-width: 500px;
    }

    body {
        font-family: &quot;Inter&quot;, sans-serif;
    }

    .formcarryContainer {
        width: var(--c-width);
        max-width: var(--c-max-width);
        display: block;
        margin: 10vh auto 0 auto;
    }

    .formcarryForm label {
        display: block;
        padding: 12px 0 2px 0;
        letter-spacing: -0.2px;
        cursor: pointer;
        font-size: 16px;
        font-weight: 700;
    }

    .formcarryForm input,
    .formcarryForm textarea {
        font-size: 16px;
        display: block;
        width: 100%;
        padding: 10px;
        background-color: var(--color-gray);
        border: none;
        border: 4px solid var(--color-gray);
        outline: none;
        border-radius: 8px;
        color: var(--color-dark-gray);
    }

    .formcarryForm input:focus,
    .formcarryForm textarea:focus {
        background-color: #fff;
        color: var(--color-dark-gray);
    }

    .formcarryForm input:focus:required:invalid {
        border-color: var(--color-pink);
        background-color: #fff;
    }

    .formcarryForm button {
        display: block;
        margin-top: 12px;
        width: 100%;
        padding: 12px 20px;
        border-radius: 8px;
        background-color: var(--color-blue);
        color: #fff;
        font-weight: 700;
        font-size: 18px;

        transition: 300ms all;
    }

    .formcarryForm button:hover {
        background-color: var(--color-light-blue);
    }

    .formcarry-alert {
        padding: 12px;
        border-radius: 10px;
        color: #fff;
        font-size: 14px;
        font-weight: 400;
        margin-top: 12px;
        display: none;
    }

    .formcarry-alert.visible {
        display: block;
    }

    .formcarry-alert.success {
        background: #69cf9d;
    }

    .formcarry-alert.error {
        background: #de524c;
    }
&lt;/style&gt;</code></pre><p>Here&apos;s the live <a href="https://codesandbox.io/s/mystifying-curie-d492f">CodeSandbox</a> demo</p><p><strong>Update 6 Jan, 2022:</strong></p><p>We have built <a href="https://formcarry.com/html-form-generator">free form generator</a> tool that you can customize and get HTML code, make sure you check it out if you need form template.</p><h2 id="step-2-structure-your-form-data">Step 2 &#x2014; Structure your form data</h2><p>In order to send your form data to a script you need to name each of your fields so the script can match the values with the names (or the key).</p><p>You can add as many fields as you want.</p><p>Let&apos;s uniquely name each of our fields using <code>name</code> attribution.</p><pre><code class="language-html">&lt;form class=&quot;formcarryForm&quot; action=&quot;#&quot; method=&quot;POST&quot;&gt;
  &lt;label for=&quot;firstNameInput&quot;&gt;First Name&lt;/label&gt;
  &lt;input type=&quot;text&quot; id=&quot;firstNameInput&quot; name=&quot;firstName&quot; /&gt;

  &lt;label for=&quot;lastNameInput&quot;&gt;Last Name&lt;/label&gt;
  &lt;input type=&quot;text&quot; id=&quot;lastNameInput&quot; name=&quot;lastName&quot; /&gt;

  &lt;label for=&quot;emailInput&quot;&gt;Email&lt;/label&gt;
  &lt;input type=&quot;email&quot; id=&quot;emailInput&quot; name=&quot;email&quot; /&gt;

  &lt;label for=&quot;messageInput&quot;&gt;Message&lt;/label&gt;
  &lt;textarea id=&quot;messageInput&quot; cols=&quot;30&quot; rows=&quot;10&quot; name=&quot;message&quot;&gt;&lt;/textarea&gt;

  &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;
</code></pre><p>Now we have a contact form that&apos;s ready to deliver the data to a script.</p><h2 id="step-3-point-your-form-to-backend">Step 3 &#x2014; Point your form to backend</h2><p>There&apos;s two ways to handle this step, this part is the most time consuming stuff due to you have to check fields, implement spam protection, create a mail server and make sure that it&apos;s working.</p><p>You can code your form backend on your own, or you can use <a href="https://formcarry.com">Formcarry &#x2014; form backend</a> to process your form for free, that way you can get notification emails, use best in class spam protection and connect your submission data with other apps using <a href="https://zapier.com">Zapier</a>.</p><p>If you want to code your own back-end take a look at <a href="https://formcarry.com/blog/how-to-create-a-html-contact-form-with-file-upload/">How to create a contact form backend on your own</a>.</p><h2 id="step-3-1-create-a-form-in-formcarry">Step 3.1 &#x2014; &#xA0;Create a form in formcarry</h2><p><a href="https://formcarry.com/register"><strong>Sign Up</strong></a> to formcarry for free, then click <strong><a href="https://formcarry.com/profile/add-form">Add New</a></strong> to get your unique form backend URL</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://formcarry.com/blog/content/images/2022/10/create_form.gif" class="kg-image" alt="How to create a working contact form with HTML" loading="lazy" width="1970" height="1439" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/create_form.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/create_form.gif 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/create_form.gif 1600w, https://formcarry.com/blog/content/images/2022/10/create_form.gif 1970w" sizes="(min-width: 720px) 720px"><figcaption>Creating a form in formcarry dashboard</figcaption></figure><p>Then copy your unique form endpoint</p><h2 id="step-3-2-integrate-your-form-with-formcarry">Step 3.2 &#x2014; Integrate your form with formcarry</h2><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/copy_endpoint.gif" class="kg-image" alt="How to create a working contact form with HTML" loading="lazy" width="1970" height="1439" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/copy_endpoint.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/copy_endpoint.gif 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/copy_endpoint.gif 1600w, https://formcarry.com/blog/content/images/2022/10/copy_endpoint.gif 1970w" sizes="(min-width: 720px) 720px"></figure><p>Copy your endpoint and paste it into <code>action</code> part of your form</p><pre><code class="language-diff">- &lt;form class=&quot;formcarryForm&quot; action=&quot;#&quot; method=&quot;POST&quot;&gt;
+ &lt;form class=&quot;formcarryForm&quot; action=&quot;https://formcarry.com/s/{Your-Unique-Endpoint}&quot; method=&quot;POST&quot;&gt;
</code></pre><h2 id="step-4-collect-submissions">Step 4 &#x2014; Collect submissions</h2><p>We have crafted our form under few minutes and now you are ready to collect submissions, let&apos;s try our form!</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/CleanShot-2022-10-23-at-22.15.49-1.gif" class="kg-image" alt="How to create a working contact form with HTML" loading="lazy" width="1970" height="1439" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/CleanShot-2022-10-23-at-22.15.49-1.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/CleanShot-2022-10-23-at-22.15.49-1.gif 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/CleanShot-2022-10-23-at-22.15.49-1.gif 1600w, https://formcarry.com/blog/content/images/2022/10/CleanShot-2022-10-23-at-22.15.49-1.gif 1970w" sizes="(min-width: 720px) 720px"></figure><p>Easy peasy &#x1F642;, now refresh your formcarry dashboard to see the submission;</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/read-submission-1.gif" class="kg-image" alt="How to create a working contact form with HTML" loading="lazy" width="1970" height="1440" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/read-submission-1.gif 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/read-submission-1.gif 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/read-submission-1.gif 1600w, https://formcarry.com/blog/content/images/2022/10/read-submission-1.gif 1970w" sizes="(min-width: 720px) 720px"></figure><p>That&apos;s how easy it is, you can filter, sort and export your submissions from your formcarry dashboard.</p><p>You&apos;ll also get an email to the email addresses you have specified when you are creating the form;</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2022/10/email-client-1.png" class="kg-image" alt="How to create a working contact form with HTML" loading="lazy" width="2000" height="1744" srcset="https://formcarry.com/blog/content/images/size/w600/2022/10/email-client-1.png 600w, https://formcarry.com/blog/content/images/size/w1000/2022/10/email-client-1.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2022/10/email-client-1.png 1600w, https://formcarry.com/blog/content/images/size/w2400/2022/10/email-client-1.png 2400w" sizes="(min-width: 720px) 720px"></figure><hr><h2 id="conclusion">Conclusion</h2><p>I hope this blog post helped you! feel free to ask down there if anything didn&apos;t go expected.</p><p>It&apos;s really time consuming thing to <a href="https://formcarry.com/blog/how-to-create-a-html-contact-form-with-file-upload/">create your own form backend</a> but formcarry offers you the best solution, here&apos;s other things that you can benefit from using formcarry:</p><ul><li><a href="https://formcarry.com/documentation/formcarry-advanced-configurations#uploading-files">Upload files to your form</a></li><li>Integrating your submissions to other apps like, <a href="https://formcarry.com/documentation/zapier#creating-a-zap-with-formcarry">Integrate formcarry with Google Sheets</a></li><li><a href="https://formcarry.com/docs/features/respondent-email-notifications">Auto Responders</a></li><li><a href="https://formcarry.com/docs/features/custom-email-templates">Customize your Emails</a></li><li>Analytics</li></ul><p>At formcarry all of our job is to make sure that your form endpoint is always online, provide you the best spam protection and allow you to always receive email notifications whenever you got a new submission!</p><p>If you haven&apos;t registered yet, <a href="https://formcarry.com/register">Register Formcarry for Free Now!</a></p>]]></content:encoded></item><item><title><![CDATA[How to create email templates using MJML - Step-by-step guide]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Although email is an old technology, it&apos;s still preserves its popularity. According to a 2017 Zapier blog post:</p>
<p>The number of people using email for team communication is more than 2.5 times higher than team chat apps like Slack.<br>
<img src="https://cdn.zapier.com/storage/photos/0b85816aabe72b69c141600c5829b137.png" alt="Email vs Team Chat" loading="lazy"></p>
<p>Email newsletters are great for following the industry,</p>]]></description><link>https://formcarry.com/blog/how-to-create-email-templates-using-mjml-script-language/</link><guid isPermaLink="false">5f840da5b646e17c1d46af17</guid><dc:creator><![CDATA[Nusu Alabuga]]></dc:creator><pubDate>Tue, 17 Nov 2020 18:13:00 GMT</pubDate><media:content url="https://formcarry.com/blog/content/images/2020/10/cvr-2.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://formcarry.com/blog/content/images/2020/10/cvr-2.png" alt="How to create email templates using MJML - Step-by-step guide"><p>Although email is an old technology, it&apos;s still preserves its popularity. According to a 2017 Zapier blog post:</p>
<p>The number of people using email for team communication is more than 2.5 times higher than team chat apps like Slack.<br>
<img src="https://cdn.zapier.com/storage/photos/0b85816aabe72b69c141600c5829b137.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"></p>
<p>Email newsletters are great for following the industry, or getting couple of discount codes. I think I have at least 15 subscriptions to different email newsletters.<br>
Yes, email is still popular, but there&apos;s a problem that wastes our time. At formcarry, our mission is saving people from wasting time. Creating email templates is a hassle, because there are various email clients, even though email is an old technology and doesn&apos;t support a big amount of HTML and CSS features. In general we mostly see that email templates are being created using HTML tables. Often the file is also full of unnecessary code: it&apos;s so big that you don&apos;t even want to edit it.</p>
<p>Thanks to the Open Source, somebody made a solution for this: MJML</p>
<h1 id="whatismjml">What is MJML?</h1>
<p><a href="https://mjml.io">MJML</a> is made by Mailjet. It&apos;s a component based markup language that allows you to create responsive emails blazing fast and easier than ever. When you finish the project, it converts your MJML code to the HTML so you can use it for your projects.</p>
<h1 id="creatinganemailtemplatewithmjml">Creating an Email Template with MJML</h1>
<p>We will code an email template design using MJML in this blog post.</p>
<h2 id="thedesign">The Design</h2>
<p>I have designed a minimal email template:<br>
<img src="https://formcarry.com/blog/content/images/2020/10/tasarim.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"></p>
<h2 id="howtoinstallmjml">How to install MJML</h2>
<p>MJML comes with several installing options for different platforms:</p>
<ul>
<li><a href="https://mjmlio.github.io/mjml-app/">MJML App</a> - This app is built just for MJML, it has an editor and live preview feature.</li>
<li><a href="https://github.com/attilabuti/vscode-mjml">Visual Studio Code plugin</a> - It&apos;s also has a live preview feature like the MJML App.</li>
<li><a href="https://atom.io/users/mjmlio">Atom Plugin</a> - It requires installing more than one package</li>
<li><a href="https://packagecontrol.io/packages/MJML-syntax">Sublime Text Plugin</a> - It&apos;s just highlighting the MJML code. (Ohh sublime, you were a legend in the earliest days.)</li>
<li><a href="https://github.com/mjmlio/mjml">Node.js</a> - npm install mjml</li>
</ul>
<p><a href="https://github.com/mjmlio/mjml">More information</a></p>
<p>We will stick with the MJML App for this demonstration. When we open the app this screen appears<br>
<img src="https://formcarry.com/blog/content/images/2020/10/1-1.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"><br>
There were some good features in options, such as minifying the exported code, configuring tab size and creating snippets are the ones I liked. I also recommend you to select the minifying option for exported code, as 27 lines of MJML turns into 296 lines of HTML, and you can leverage this.</p>
<p>Click the New Project, enter the project&apos;s name and you&apos;ll see this screen:<br>
<img src="https://formcarry.com/blog/content/images/2020/10/2.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"><br>
You have options in there: you can go with basic empty layout or you can choose something from the gallery<br>
<img src="https://formcarry.com/blog/content/images/2020/10/3.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"></p>
<p>We&apos;re going to code it from scratch, so let&apos;s go with single file, basic layout.<br>
<img src="https://formcarry.com/blog/content/images/2020/10/4.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"></p>
<h2 id="firstlook">First look</h2>
<p>Let&apos;s observe the code. It seems there are so many things in common with HTML:</p>
<ul>
<li>An HTML file will start with <code>&lt;html&gt;</code> and end with <code>&lt;/html&gt;</code>, MJML is using the same methodology</li>
<li><code>&lt;mj-head&gt;&lt;/mj-head&gt;</code> is equivalent of <code>&lt;head&gt;&lt;/head&gt;</code> tags in the HTML, same way the <code>&lt;mj-body&gt;&lt;/mj-body&gt;</code> is <code>&lt;body&gt;&lt;/body&gt;</code></li>
<li>We can define our styles in <code>&lt;mj-attributes&gt;&lt;/mj-attributes&gt;</code> just like in the HTML <code>&lt;style&gt;&lt;/style&gt;</code></li>
<li>We can give an inline-style like in the HTML, yet while HTML wraps the style attributes in style=&quot;&quot; block, MJML uses it directly with property name and value</li>
<li>mj-section and mj-column is using a grid system. <a href="https://www.sitepoint.com/understanding-css-grid-systems/">(What is a grid system ?)</a></li>
</ul>
<p>After the quick overview, let&apos;s code. First of all let&apos;s clean the unnecessary codes in our file.</p>
<pre><code>&lt;mjml&gt;
  &lt;mj-head&gt;

  &lt;/mj-head&gt;
  &lt;mj-body&gt;
    
  &lt;/mj-body&gt;
&lt;/mjml&gt;
</code></pre>
<p>A reminder of our design:<br>
<img src="https://formcarry.com/blog/content/images/2020/10/tasarim.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"></p>
<p>I have used the <a href="https://fonts.google.com/specimen/Montserrat">Montserrat</a> font, which is free to use, for this demo. In order to add fonts in MJML, we need to add this code right after the <code>&lt;mj-head&gt;</code>.</p>
<pre><code>&lt;mj-head&gt;
  &lt;mj-font name=&quot;Montserrat&quot; href=&quot;https://fonts.googleapis.com/css?family=Montserrat:400,500,600,700&quot; /&gt;
  &lt;mj-attributes&gt;
    &lt;mj-all font-family=&quot;Montserrat&quot; /&gt;
  &lt;/mj-attributes&gt;
&lt;/mj-head&gt;
</code></pre>
<p>I also added the mj-attributes for setting Montserrat as the default font for this template.</p>
<p>Now I&apos;m going to export my sample logo and paste it into the MJML project directory.</p>
<pre><code>&lt;mj-hero padding=&quot;40px&quot;&gt;
  &lt;mj-image align=&quot;left&quot; width=&quot;138px&quot; src=&quot;logo.png&quot;/&gt;
&lt;/mj-hero&gt;
</code></pre>
<p>By default images aligned at center, if you want to align it to the left or right, you need to set &quot;align&quot; attribute.<br>
This is how it looks right now:<br>
<img src="https://formcarry.com/blog/content/images/2020/10/5.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"><br>
Then we need 3 text elements and one button; Let&apos;s do that, we will use <code>mj-text</code> for texts and <code>mj-button</code> for <code>button</code> and a padding for mj-section</p>
<pre><code>&lt;mj-section padding=&quot;40px&quot;&gt;

    &lt;mj-column&gt;

        &lt;mj-text&gt;
          Verify Your Email
        &lt;/mj-text&gt;

        &lt;mj-text&gt;
          Hi Jhony! Use the link below to verify your email
    address.
        &lt;/mj-text&gt;

        &lt;mj-button&gt;
            It&apos;s Me, Jhony!
        &lt;/mj-button&gt;

        &lt;mj-text&gt;
          If you are not the Johny, we are sorry.
        &lt;/mj-text&gt;

    &lt;/mj-column&gt;

&lt;/mj-section&gt;
</code></pre>
<p>How it looks:<br>
<img src="https://formcarry.com/blog/content/images/2020/10/6.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"><br>
Now we need to style that and finish our example. We just have to use CSS attributes in <code>mj-text</code> and <code>mj-button</code> elements.</p>
<pre><code>&lt;mj-text font-size=&quot;29px&quot; font-weight=&quot;700&quot; color=&quot;#222222&quot; padding-bottom=&quot;30px&quot;&gt;
    Verify Your Email
&lt;/mj-text&gt;
</code></pre>
<p><img src="https://formcarry.com/blog/content/images/2020/10/7.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"></p>
<p>Now style the paragraph and the notice text.</p>
<pre><code>&lt;mj-text font-size=&quot;18px&quot; color=&quot;#9798A4&quot; font-weight=&quot;400&quot; line-height=&quot;27px&quot; padding-bottom=&quot;60px&quot;&gt;
  Hi Jhony! Use the link below to verify your email
address.
&lt;/mj-text&gt;
...
&lt;mj-text font-size=&quot;11px&quot; color=&quot;#9798A4&quot; font-weight=&quot;500&quot; padding-top=&quot;30px&quot;&gt;
      If you are not the Jhony, we are sorry.
&lt;/mj-text&gt;        
</code></pre>
<p>How it looks:<br>
<img src="https://formcarry.com/blog/content/images/2020/10/8.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"></p>
<p>We just have to style our button right now; let&apos;s do it.</p>
<pre><code>&lt;mj-button href=&quot;#&quot; width=&quot;100%&quot; inner-padding=&quot;25px&quot; border-radius=&quot;6px&quot; background-color=&quot;#005BF2&quot; font-size=&quot;22px&quot; font-weight=&quot;500&quot; color=&quot;#fff&quot;&gt;
      It&apos;s Me, Jhony!
&lt;/mj-button&gt;
</code></pre>
<p>Looks perfect:<br>
<img src="https://formcarry.com/blog/content/images/2020/10/9.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"><br>
Without the spaces, this is only 22 lines of code, yet when we transform it to the HTML it becomes 296 lines of code (unminified).</p>
<p>We can export our file in the dropdown menu. Click to the down arrow to open it.<br>
<img src="https://formcarry.com/blog/content/images/2020/10/10.png" alt="How to create email templates using MJML - Step-by-step guide" loading="lazy"></p>
<p>Looks perfect. If you want to dive deeper you can take a look at <a href="https://mjml.io/documentation">MJML Documentation</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide]]></title><description><![CDATA[How to create an HTML contact form with file upload to Amazon S3 using Node.js and Express.js]]></description><link>https://formcarry.com/blog/how-to-create-a-html-contact-form-with-file-upload/</link><guid isPermaLink="false">5f841ab8b646e17c1d46af28</guid><dc:creator><![CDATA[Nusu Alabuga]]></dc:creator><pubDate>Sun, 18 Oct 2020 09:08:00 GMT</pubDate><media:content url="https://formcarry.com/blog/content/images/2020/10/cvr-1-2.png" medium="image"/><content:encoded><![CDATA[<img src="https://formcarry.com/blog/content/images/2020/10/cvr-1-2.png" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide"><p>In this tutorial, we are going to create a sample app using Express.js to upload files to Amazon S3, then we are going to save our submission to the MongoDB</p><h2 id="prerequisites-for-the-tutorial">Prerequisites for the tutorial</h2><p>I don&apos;t want to cover some things that would over-complicate this tutorial, therefore I assume you know how to:</p><ul><li>Get your API keys from Amazon AWS</li><li>Create a bucket on Amazon S3</li></ul><p>If you don&apos;t know how to do that, you can take a look at this <a href="https://medium.com/@shamnad.p.s/how-to-create-an-s3-bucket-and-aws-access-key-id-and-secret-access-key-for-accessing-it-5653b6e54337">blog post</a>, it&apos;s fairly simple to follow.</p><h2 id="steps-we-are-going-to-follow">Steps we are going to follow</h2><ul><li>Create a Contact Form using HTML</li><li>Bootstrap an Express.js app</li><li>Parsing form data</li><li>Uploading the file to S3</li><li>Saving the data to MongoDB</li></ul><h2 id="let-s-create-a-simple-contact-form-using-html">Let&apos;s create a simple contact form using HTML</h2><p>The key things when creating an upload form are the attributes you defined in <code>&lt;form&gt;</code>.</p><p>Let&apos;s create a simple form:</p><pre><code>&lt;form action=&quot;#&quot; method=&quot;POST&quot;&gt;
    &lt;label for=&quot;email&quot;&gt;Email Address&lt;/label&gt;
    &lt;input type=&quot;email&quot; id=&quot;email&quot; name=&quot;email&quot;&gt;

    &lt;label for=&quot;fullName&quot;&gt;Full Name&lt;/label&gt;
    &lt;input type=&quot;text&quot; id=&quot;fullName&quot; name=&quot;fullName&quot;&gt;

    &lt;label for=&quot;message&quot;&gt;Message&lt;/label&gt;
    &lt;textarea name=&quot;message&quot; id=&quot;message&quot;&gt;&lt;/textarea&gt;

    &lt;label for=&quot;photo&quot;&gt;Photo&lt;/label&gt;
    &lt;input type=&quot;file&quot; id=&quot;photo&quot; name=&quot;photo&quot;&gt;

    &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;</code></pre><p>We have built <a href="https://formcarry.com/html-form-generator">free form generator</a> tool that you can customize and get HTML code, make sure you check it out if you need form template.</p><p>In the software world, most of the configurable options have a default value that will apply unless you override it, and one of these for <code>form</code> is <code>enctype</code>.</p><p>When you make an request to the backend, you have to encode the form data, there are 3 options available for <code>enctype</code>:</p><ul><li><code>application/x-www-form-urlencoded</code> (default)</li><li><code>multipart/form-data</code></li><li><code>text/plain</code></li></ul><p>Through the <a href="https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4">w3 specification</a>;</p><blockquote>The content type &quot;application/x-www-form-urlencoded&quot; is inefficient for sending large quantities of binary data or text containing non-ASCII characters.<br>The content type &quot;multipart/form-data&quot; should be used for submitting forms that contain files, non-ASCII data, and binary data.</blockquote><p><em>Also unless you really know what you are doing, do not ever use <code>text/plain</code> (<a href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#text%2Fplain-encoding-algorithm">click here for why</a>.)</em></p><p>So what we want to do is set <code>enctype</code> to <code>multipart/form-data</code></p><pre><code class="language-diff">- &lt;form action=&quot;#&quot; method=&quot;POST&quot;&gt;
+ &lt;form action=&quot;#&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
	&lt;label for=&quot;email&quot;&gt;Email Address&lt;/label&gt;
    &lt;input type=&quot;email&quot; id=&quot;email&quot; name=&quot;email&quot;&gt;

    &lt;label for=&quot;fullName&quot;&gt;Full Name&lt;/label&gt;
    &lt;input type=&quot;text&quot; id=&quot;fullName&quot; name=&quot;fullName&quot;&gt;

    &lt;label for=&quot;message&quot;&gt;Message&lt;/label&gt;
    &lt;textarea name=&quot;message&quot; id=&quot;message&quot;&gt;&lt;/textarea&gt;

    &lt;label for=&quot;photo&quot;&gt;Photo&lt;/label&gt;
    &lt;input type=&quot;file&quot; id=&quot;photo&quot; name=&quot;photo&quot;&gt;

    &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;</code></pre><p>Now we have a simple contact form that&apos;s ready to send data to our express app that we&apos;re going to develop now. Let&apos;s save this to somewhere for now.</p><h2 id="bootstrap-an-express-js-app">Bootstrap an Express.js app</h2><p>I assume that you&apos;ve already installed <a href="https://nodejs.org/">Node.js</a>.<br>Let&apos;s create and directory for our application using terminal/bash</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">$ mkdir my-form my-form/views
$ cd my-form</code></pre><figcaption>create the directory my-app and views to store our contact form, then get into the directory</figcaption></figure><p>Use the <code>npm init</code> command to initialize our project.</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">$ npm init</code></pre><figcaption>initialize the project</figcaption></figure><p>Just hit <code>enter</code> for everything, and install express.js using:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">$ npm install express express-fileupload --save
$ npm install nodemon -g</code></pre><figcaption>install express.js and save it to the package.json</figcaption></figure><p>Now we have a directory structure like this:</p><figure class="kg-card kg-code-card"><pre><code>.
|____my-form
| |____package.json
| |____views
</code></pre><figcaption>directory tree of our project</figcaption></figure><p>Save the form that we created in the beginning under the views folder as <code>form.html</code></p><figure class="kg-card kg-code-card"><pre><code>.
|____my-form
| |____index.js
| |____package.json
| |____views
| | |____form.html</code></pre><figcaption>directory tree (again) of our project</figcaption></figure><p>Let&apos;s create our <code>index.js</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const express = require(&apos;express&apos;)
const app = express()
const fileUpload = require(&apos;express-fileupload&apos;)

app.use(fileUpload({
  // 50mb file limit
  limits: { fileSize: 50 * 1024 * 1024 },
  abortOnLimit: true
}));

app.get(&apos;/&apos;, (req, res) =&gt; {
  res.sendFile(&apos;views/form.html&apos; , { root : __dirname});
})

// endpoint that will handle the form
app.post(&apos;/submit&apos;, (req, res) =&gt; {
  const {body, files} = req
  res.send({body, files})
})

const port = 3031

app.listen(port, () =&gt; {
  console.log(`Application is available at http://localhost:${port}`)
})</code></pre><figcaption>index.js</figcaption></figure><p>Save it, then open the <code>form.html</code> and point the form to the <code>/submit</code> endpoint we just created with express app:</p><figure class="kg-card kg-code-card"><pre><code class="language-diff">- &lt;form action=&quot;#&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
+ &lt;form action=&quot;/submit&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;</code></pre><figcaption>form.html</figcaption></figure><hr><h3 id="don-t-have-much-time-for-a-form">Don&apos;t have much time for a form?</h3><p>File upload is not something you can achieve instantly, so if you want to have a quick and simple solution, check out our other blog post.</p><figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="https://formcarry.com/blog/how-to-create-a-file-upload-form-with-formcarry/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">How to create a file upload form with formcarry</div><div class="kg-bookmark-description">One of the most time consuming thing about forms is definitely uploading files,sometimes you may need an HTML form with file upload functionality, in thisguide we are going to start by as simple as possible than we are going to jumpto advanced techniques After you read this guide * You can crea&#x2026;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://formcarry.com/blog/favicon.png" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide"><span class="kg-bookmark-author">Formcarry Blog</span><span class="kg-bookmark-publisher">Nusu Alabuga</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://formcarry.com/blog/content/images/2021/07/file-upload-form.png" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide"></div></a><figcaption>how to create a file upload form with formcarry</figcaption></figure><hr><p>Now let&apos;s add some style:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;Contact Form&lt;/title&gt;
  &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Inter&amp;display=swap&quot; rel=&quot;stylesheet&quot;&gt;
  &lt;style&gt;
    body {
      font-family: &quot;Inter&quot;;
    }

    label, button {
      font-size: 16px;
      cursor: pointer;
    }

    input, textarea {
      border: 3px solid #eee;
      padding: .4em 1em;
      border-radius: 6px;
    }

    form {
      display: grid;
      grid-row-gap: 10px;
      justify-content: center;
    }

    button {
      margin-top: 10px;
      background: #133EF5;
      color: #fff;
      padding: 10px 0;
      border: 0;
      border-radius: 6px;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;form action=&quot;/submit&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
    &lt;label for=&quot;email&quot;&gt;Email Address&lt;/label&gt;
    &lt;input type=&quot;email&quot; id=&quot;email&quot; name=&quot;email&quot;&gt;

    &lt;label for=&quot;fullName&quot;&gt;Full Name&lt;/label&gt;
    &lt;input type=&quot;text&quot; id=&quot;fullName&quot; name=&quot;fullName&quot;&gt;

    &lt;label for=&quot;message&quot;&gt;Message&lt;/label&gt;
    &lt;textarea name=&quot;message&quot; id=&quot;message&quot;&gt;&lt;/textarea&gt;

    &lt;label for=&quot;photo&quot;&gt;Photo&lt;/label&gt;
    &lt;input type=&quot;file&quot; id=&quot;photo&quot; name=&quot;photo&quot;&gt;

    &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
  &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><figcaption>form.html</figcaption></figure><p>Finally run:</p><pre><code class="language-bash">$ nodemon index.js</code></pre><p>Then visit <code>http://localhost:3031</code> from your browser:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://formcarry.com/blog/content/images/2020/10/image.png" class="kg-image" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide" loading="lazy" width="1518" height="1446" srcset="https://formcarry.com/blog/content/images/size/w600/2020/10/image.png 600w, https://formcarry.com/blog/content/images/size/w1000/2020/10/image.png 1000w, https://formcarry.com/blog/content/images/2020/10/image.png 1518w" sizes="(min-width: 720px) 720px"><figcaption>form.html</figcaption></figure><p>Fill out the form with sample data and file then submit.<br>You will see something like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://formcarry.com/blog/content/images/2020/10/image-3.png" class="kg-image" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide" loading="lazy" width="1518" height="1446" srcset="https://formcarry.com/blog/content/images/size/w600/2020/10/image-3.png 600w, https://formcarry.com/blog/content/images/size/w1000/2020/10/image-3.png 1000w, https://formcarry.com/blog/content/images/2020/10/image-3.png 1518w" sizes="(min-width: 720px) 720px"><figcaption>sorry Peter, 404 not found &#x1F97A;</figcaption></figure><blockquote>use <a href="https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc">JSONView Chrome Extension</a> to display JSON content like &#x1F446;</blockquote><p>Great, now we are ready to do the rest, let&apos;s clarify something before getting going:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://formcarry.com/blog/content/images/2020/10/image-4.png" class="kg-image" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide" loading="lazy" width="2000" height="924" srcset="https://formcarry.com/blog/content/images/size/w600/2020/10/image-4.png 600w, https://formcarry.com/blog/content/images/size/w1000/2020/10/image-4.png 1000w, https://formcarry.com/blog/content/images/size/w1600/2020/10/image-4.png 1600w, https://formcarry.com/blog/content/images/size/w2400/2020/10/image-4.png 2400w" sizes="(min-width: 1200px) 1200px"><figcaption>how your data transmitted to the backend application</figcaption></figure><p>As you can see with the picture above, whatever you define for <code>name</code> will be present on the backend with same value, so if you don&apos;t name your fields then you can&apos;t parse them.<br>This is an common mistake so be careful &#x1F575;&#xFE0F;</p><h3 id="configuring-aws-sdk">Configuring AWS-SDK</h3><p>Let&apos;s install <code>aws-sdk</code>:</p><pre><code class="language-bash">$ npm install aws-sdk --save</code></pre><p>Then import it and use the keys that you have obtained from AWS:</p><figure class="kg-card kg-code-card"><pre><code class="language-diff">const express = require(&apos;express&apos;)
const app = express()
const fileUpload = require(&apos;express-fileupload&apos;)
+ const AWS = require(&apos;aws-sdk&apos;)

+ AWS.config.update({
+  accessKeyId: &apos;&lt;Replace with your access key&gt;&apos;,
+  secretAccessKey: &apos;&lt;Replace with your secret key&gt;&apos;
+ })

+ const s3 = new AWS.S3({ params: { Bucket: &apos;&lt;Replace with your bucket name&gt;&apos; }});

app.use(fileUpload({
  // 50mb file limit
  limits: { fileSize: 50 * 1024 * 1024 },
  abortOnLimit: true
}));

app.get(&apos;/&apos;, (req, res) =&gt; {
  res.sendFile(&apos;views/form.html&apos; , { root : __dirname});
})

app.post(&apos;/submit&apos;, (req, res) =&gt; {
  const { body, files } = req
  res.send({body, files})
})

const port = 3031

app.listen(port, () =&gt; {
  console.log(`Application is available at http://localhost:${port}`)
})</code></pre><figcaption>Replace your access key, secret key and bucket name</figcaption></figure><h2 id="uploading-file">Uploading File</h2><p>We are ready to upload now, first let&apos;s transform our function to an async function:</p><figure class="kg-card kg-code-card"><pre><code class="language-diff">- app.post(&apos;/submit&apos;, (req, res) =&gt; {
+ app.post(&apos;/submit&apos;, async (req, res) =&gt; {</code></pre><figcaption>index.js</figcaption></figure><p>Then let&apos;s add the code that manages upload:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">app.post(&apos;/submit&apos;, async (req, res) =&gt; {
  const { files } = req

  try {
    const upload = new AWS.S3.ManagedUpload({
      params: { 
        // pass directly the buffer string
        Body: files.photo.data, 
        // pass the file name
        Key: files.photo.name,
        // make it public
        ACL: &apos;public-read&apos;
      },
      // use the const s3 that we defined above
      service: s3,
    })

    const response = await upload.promise()

    res.send(response)
  } catch (error) {
    res.send(error)
  }
})</code></pre><figcaption>Upload the file to the Amazon S3 | index.js</figcaption></figure><h3 id="so-what-s-happening-there">So what&apos;s happening there?</h3><p>We destructured the <code>req</code> object that holds the files, so <code>const files</code> is equivalent of <code>req.files</code>.<br>Let&apos;s remember our test payload.</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2020/10/image-5.png" class="kg-image" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide" loading="lazy" width="1518" height="1446" srcset="https://formcarry.com/blog/content/images/size/w600/2020/10/image-5.png 600w, https://formcarry.com/blog/content/images/size/w1000/2020/10/image-5.png 1000w, https://formcarry.com/blog/content/images/2020/10/image-5.png 1518w" sizes="(min-width: 720px) 720px"></figure><p>Everything under <code>files</code> key is provided by <a href="https://github.com/richardgirges/express-fileupload">express-fileupload</a> module, which handles the files and returns them in a nice and usable structure.</p><p><code>AWS.S3.ManagedUpload</code> and <code>AWS.S3.Upload</code> can accept &#xA0;<code>Buffer, Typed Array, Blob, String, ReadableStream</code>. While our <code>files.photo.data</code> is a <code>Buffer</code> we can directly pass that to the <code>Body</code> parameter .</p><p><code>ACL</code> is shorthand for Access Control List, which we&apos;ve set to <code>public-read</code> to view the uploaded file.</p><p><code>Key</code> is the name of our file.</p><h2 id="let-s-try-it">Let&apos;s try it</h2><p>Visit <code>http://localhost:3031/</code> and fill out the fields. You don&apos;t necessarily have to fill anything other than the file because we haven&apos;t done anything with it yet.</p><p>After you click the <em>Submit </em>button, you will see something like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://formcarry.com/blog/content/images/2020/10/image-7.png" class="kg-image" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide" loading="lazy" width="1518" height="1446" srcset="https://formcarry.com/blog/content/images/size/w600/2020/10/image-7.png 600w, https://formcarry.com/blog/content/images/size/w1000/2020/10/image-7.png 1000w, https://formcarry.com/blog/content/images/2020/10/image-7.png 1518w" sizes="(min-width: 720px) 720px"><figcaption>Uploaded File</figcaption></figure><p>Then check your bucket and you will see the file in the bucket.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://formcarry.com/blog/content/images/2020/10/image-6.png" class="kg-image" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide" loading="lazy" width="1450" height="590" srcset="https://formcarry.com/blog/content/images/size/w600/2020/10/image-6.png 600w, https://formcarry.com/blog/content/images/size/w1000/2020/10/image-6.png 1000w, https://formcarry.com/blog/content/images/2020/10/image-6.png 1450w" sizes="(min-width: 720px) 720px"><figcaption>S3 Dashboard</figcaption></figure><p>It worked! Now we have form data and the uploaded file details, we can use this data to save to the database or send some webhook.</p><h3 id="renaming-the-files">Renaming the files</h3><p>It&apos;s not a wise choice to use the original file name, in case someone else uploads a file with the same name, it&apos;s better to write a simple function to generate a random name:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const path = require(&apos;path&apos;);

const generateUniqueFileName = (fileName) =&gt; {
  const extension = path.extname(fileName)
  const date = Date.now();

  let randomHash = &apos;&apos;
  const characters = &apos;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&apos;;
  
  new Array(20).fill(null).map(_ =&gt; {
    randomHash += characters.charAt(Math.floor(Math.random() * characters.length));
  })

  return `${randomHash}-${date}${extension}`
}</code></pre><figcaption>random name generator&#xA0;</figcaption></figure><p>It&apos;s not even a wise choice to depend on only a random generated string: it&apos;s better to add something unique to that time, like time &#x23F1; itself using <code>Date.now();</code></p><figure class="kg-card kg-code-card"><pre><code class="language-diff">const upload = new AWS.S3.ManagedUpload({
  params: { 
    // pass directly the buffer string
    Body: files.photo.data, 
    // pass the file name
-   Key: files.photo.name,
+   Key: generateUniqueFileName(files.photo.name),
    // make it public
    ACL: &apos;public-read&apos;
  },
  // use the const s3 that we defined above
  service: s3,
})</code></pre><figcaption>it will output something like =&gt; <em>cm0avQtXfOAo1PEdJxZZ-1602531725730.jpg</em></figcaption></figure><h2 id="saving-the-messages-to-the-mongodb-optional-">Saving the messages to the MongoDB (Optional)</h2><p>Now, because we have the file and form message, we can save them into the database.<br>I&apos;m going to use MongoDB for this purpose. I assume that you have a working MongoDB setup; if you don&apos;t you can checkout <a href="https://docs.mongodb.com/manual/installation/">this page</a></p><p>I&apos;m going to use <strong>mongoose </strong>npm package in order to do the operations inside our express.js app</p><h3 id="install-mongoose">Install Mongoose</h3><figure class="kg-card kg-code-card"><pre><code class="language-bash">$ npm install mongoose --save</code></pre><figcaption>Install mongoose using npm</figcaption></figure><h3 id="create-a-mongodb-database">Create A MongoDB Database</h3><figure class="kg-card kg-code-card"><pre><code class="language-bash">$ mongo
$ use contactform</code></pre><figcaption>Create contactform database using Mongo CLI</figcaption></figure><h3 id="import-mongoose">Import Mongoose</h3><p>Add this code to index.js</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const mongoose = require(&apos;mongoose&apos;)

mongoose.connect(&apos;mongodb://localhost:27017/contactform&apos;);</code></pre><figcaption>index.js</figcaption></figure><h3 id="create-model">Create Model</h3><p>First let&apos;s create a directory called <strong>models</strong> under our project root, than create <code>form.js</code> into it</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">mkdir models
touch models/form.js</code></pre><figcaption>create models directory and models/form.js</figcaption></figure><p>Open the empty <code>form.js</code> using your code editor, and paste this:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const mongoose = require(&apos;mongoose&apos;);

const form = new mongoose.Schema({
  fullName: String,
  email: String,
  message: String,
  photo: String,
});

module.exports = mongoose.model(&apos;form&apos;, form);</code></pre><figcaption>our form model</figcaption></figure><p>Models are basically MongoDB Schema on steroids - you can take a look at them <a href="https://mongoosejs.com/docs/models.html">here</a> to learn more. All of the fields I defined are the fields we have in our <code>form.html</code></p><h3 id="import-our-model">Import our Model</h3><p>Let&apos;s import our model into the <code>index.js</code></p><figure class="kg-card kg-code-card"><pre><code class="language-diff">const mongoose = require(&apos;mongoose&apos;)

mongoose.connect(&apos;mongodb://localhost:27017/contactform&apos;);

+ const Form = require(&apos;./models/form&apos;)</code></pre><figcaption>index.js</figcaption></figure><h2 id="saving-the-form-message">Saving the form message</h2><p>Let&apos;s change our main route for saving the submission:</p><figure class="kg-card kg-code-card"><pre><code class="language-diff">app.post(&apos;/submit&apos;, async (req, res) =&gt; {
  const { files } = req

  try {
    const upload = new AWS.S3.ManagedUpload({
      params: { 
        // pass directly the buffer string
        Body: files.photo.data, 
        // pass the file name
        Key: generateUniqueFileName(files.photo.name),
        // make it public
        ACL: &apos;public-read&apos;
      },
      // use the const s3 that we defined above
      service: s3,
    })

    const response = await upload.promise()

+    const { fullName, email, message } = req.body
+    const submission = new Form({
+      fullName: fullName,
+      email: email,
+      message: message,
+      photo: response.Location
+    })

+    submission.save()

-    res.send(response)
+    res.send(submission)
  } catch (error) {
    res.send(error)
  }
})</code></pre><figcaption>Saving submission to our form model</figcaption></figure><h3 id="little-trick">Little trick</h3><p>While the key and the value are same we can convert our code to this:</p><pre><code>const submission = new Form({
  fullName,
  email,
  message,
  photo: response.Location
})</code></pre><h2 id="let-s-try-it-1">Let&apos;s try it</h2><p>Visit <code>https://localhost:3031</code> and fill the fields</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2020/10/Screen-Shot-2020-10-19-at-5.47.29-PM.png" class="kg-image" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide" loading="lazy" width="1518" height="1446" srcset="https://formcarry.com/blog/content/images/size/w600/2020/10/Screen-Shot-2020-10-19-at-5.47.29-PM.png 600w, https://formcarry.com/blog/content/images/size/w1000/2020/10/Screen-Shot-2020-10-19-at-5.47.29-PM.png 1000w, https://formcarry.com/blog/content/images/2020/10/Screen-Shot-2020-10-19-at-5.47.29-PM.png 1518w" sizes="(min-width: 720px) 720px"></figure><p>Click Submit, then:</p><figure class="kg-card kg-image-card"><img src="https://formcarry.com/blog/content/images/2020/10/Screen-Shot-2020-10-19-at-5.47.44-PM.png" class="kg-image" alt="How to create an HTML contact form with file upload to Amazon S3 | Step-by-step guide" loading="lazy" width="1518" height="1446" srcset="https://formcarry.com/blog/content/images/size/w600/2020/10/Screen-Shot-2020-10-19-at-5.47.44-PM.png 600w, https://formcarry.com/blog/content/images/size/w1000/2020/10/Screen-Shot-2020-10-19-at-5.47.44-PM.png 1000w, https://formcarry.com/blog/content/images/2020/10/Screen-Shot-2020-10-19-at-5.47.44-PM.png 1518w" sizes="(min-width: 720px) 720px"></figure><p>That&apos;s it! now you have a perfectly functional form.</p><hr><h2 id="alternative-and-simple-way-use-formcarry">Alternative and Simple Way: Use Formcarry</h2><p>By no means all of those process are time consuming stuff, we have an offer for you, feel free to try <a href="https://formcarry.com">formcarry - form backend</a>, instead of coding everything on your own you can have a file upload ready form in under a minute just by changing your form&apos;s action attribute</p><pre><code class="language-html">&lt;form action=&quot;https://formcarry.com/s/{YOUR_FORM_ID}&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
    &lt;label for=&quot;email&quot;&gt;Email Address&lt;/label&gt;
    &lt;input type=&quot;email&quot; id=&quot;email&quot; name=&quot;email&quot;&gt;

    &lt;label for=&quot;fullName&quot;&gt;Full Name&lt;/label&gt;
    &lt;input type=&quot;text&quot; id=&quot;fullName&quot; name=&quot;fullName&quot;&gt;

    &lt;label for=&quot;message&quot;&gt;Message&lt;/label&gt;
    &lt;textarea name=&quot;message&quot; id=&quot;message&quot;&gt;&lt;/textarea&gt;

    &lt;label for=&quot;photo&quot;&gt;Photo&lt;/label&gt;
    &lt;input type=&quot;file&quot; id=&quot;photo&quot; name=&quot;photo&quot;&gt;

    &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
  &lt;/form&gt;</code></pre><p>Comparing the steps above, formcarry is a very fast and secure way to collecting submissions with file attachments, use it in your contact forms, job application forms, or event forms as you need.</p><p>Grab your Form ID from <a href="https://formcarry.com/register">here</a> for free!</p>]]></content:encoded></item></channel></rss>