<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bootstrapper's Tales</title>
    <description>The latest articles on DEV Community by Bootstrapper's Tales (@bs_tales).</description>
    <link>https://dev.to/bs_tales</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F624094%2Fcc281955-5a5b-45d0-ab06-eb2ace661fbc.png</url>
      <title>DEV Community: Bootstrapper's Tales</title>
      <link>https://dev.to/bs_tales</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bs_tales"/>
    <language>en</language>
    <item>
      <title>I tested my value proposition using Facebook and Reddit ads. Here are the results!</title>
      <dc:creator>Bootstrapper's Tales</dc:creator>
      <pubDate>Mon, 12 Jul 2021 14:37:25 +0000</pubDate>
      <link>https://dev.to/bs_tales/i-tested-my-value-proposition-using-facebook-and-reddit-ads-here-are-the-results-p5e</link>
      <guid>https://dev.to/bs_tales/i-tested-my-value-proposition-using-facebook-and-reddit-ads-here-are-the-results-p5e</guid>
      <description>&lt;p&gt;During the last few weeks I was working on &lt;a href="https://ufeed.app"&gt;uFeed&lt;/a&gt;{:target="_blank"}. With uFeed users can subscribe to any newsletter or save any article to a personal feed. Think all of your content from anywhere online in a twitter-like feed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8UnJCYm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qi362ycgpbycar78fyte.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8UnJCYm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qi362ycgpbycar78fyte.jpeg" alt="uFeed - your personal feed" title="uFeed - your personal feed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Value Propositions
&lt;/h2&gt;

&lt;p&gt;I was thinking about a few value propositions I can lean into:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Make reading a habit":&lt;/strong&gt; Focus on the ability to curate your own feed in an engaging format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Your personal newsletter feed":&lt;/strong&gt; Focus on people who are subscribed to many newsletters and are overwhelmed. uFeed can free their inbox.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Make your 💩💩💩 productive":&lt;/strong&gt; Focus on productivity - help users use their breaks to catch up on content.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Designing the test
&lt;/h2&gt;

&lt;p&gt;I decided to run an ad campaign on Facebook and Reddit to test different copies. I allocated $50, which should buy me around 5000 impressions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reddit
&lt;/h2&gt;

&lt;p&gt;Reddit campaigns are quick and easy to set up. I recommend it as a testing tool. You can target specific subreddits, so you know exactly who your target audience is.&lt;/p&gt;

&lt;p&gt;Because Reddit Ads are mainly text, it's fast to spin-up and you don't need to worry about images. You can focus on the message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GKjFKcDX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3un5a6nrntda15qkkiq3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GKjFKcDX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3un5a6nrntda15qkkiq3.png" alt="Reddit campaign stats" title="Reddit campaign stats"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before diving into the results, I want to caveat that my sample size is small. It's a fun learning opportunity, but I need more iterations and $$$ to make a conclusion.&lt;/p&gt;

&lt;p&gt;6 out of my 7 clicks came from the "Make your 💩💩💩 breaks productive" ad. Also 6 out of 7 clicks came from users who are interested in personal finance. One of them even converted to a user.&lt;/p&gt;

&lt;p&gt;Reddit ads are great (easy to set up, easy to target). Here is where they lack:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I can break some of the results by subreddit, but not all of them. It's probably a sample size issue, but it's inconsistent and the UI is unclear.&lt;/li&gt;
&lt;li&gt;Reddit lacks A/B testing capabilities. Even though I've launched all of the ads at the same time, some got 800 views while others 200.&lt;/li&gt;
&lt;li&gt;In the first few days I only had 3-5 impressions per day. I thought there's something wrong with my campaign. But then, w/o changing anything, it exploded . I went up to 3000 impressions in 3 days. I have no idea why.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Facebook
&lt;/h2&gt;

&lt;p&gt;Facebook campaigns are harder to set up. There are way more settings and you need to create images in different sizes (for different placements). It's just annoying.&lt;/p&gt;

&lt;p&gt;The great thing about FB is their targeting capabilities and that you don't have  to define CPC or budding. Just specify a daily budget.&lt;/p&gt;

&lt;p&gt;Anyway, I created two ads.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZKw7oVi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f37r6r6zx5d6kqx363dq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZKw7oVi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f37r6r6zx5d6kqx363dq.png" alt="Facebook Ad Newsletters" title="Facebook Ad Newsletters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Uk-LUjCg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2rlls2sxhkk2abwicfl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Uk-LUjCg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2rlls2sxhkk2abwicfl1.png" alt="Facebook Ad Newsletters" title="Facebook Ad Reading"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And with Facebook I could run a true A/B test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e61lbwy1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ha5a1dz715jy3flx3ghc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e61lbwy1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ha5a1dz715jy3flx3ghc.png" alt="Facebook Ad Campaign Results" title="Facebook Ad Newsletters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the results for the Reddit campaign are questionable, here it's simply not usable. The sample size is so low, I cannot conclude anything. My power is 0.06%, so I have a high false negative rate.&lt;/p&gt;

&lt;p&gt;I hoped that FB could show me the type of users who would be interested in my product. My sample size is anyway too low, but I don't even see a tool like this available. I wish I could just spend, let's say $1000, and have FB tell me what kind of people are most likely to convert. I guess I need to set-up different campaigns, targeting different audiences and see what works best.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;This was a great learning experience. But, I'll need a significantly larger budget to actually draw solid conclusions.&lt;/li&gt;
&lt;li&gt;I learned from Reddit that "Make your 💩💩💩 productive" attracts clicks. It may not be the best converter of paying users, but for now I'll stick with that.&lt;/li&gt;
&lt;li&gt;The personal finance angle from Reddit is an interesting one. Nothing strong enough to change my marketing plan, but a good tidbit to keep in mind.&lt;/li&gt;
&lt;li&gt;Reddit is easy to use but lacks many features and the UX is confusing. FB is highly complex, with many different tools and settings. Reddit is your best bet if you are pressed on time or budget. FB is the way to go if you have the time to learn and figure out the platform.&lt;/li&gt;
&lt;li&gt;Either way the most important factor to decide between the two platforms is where do your customers hang out.&lt;/li&gt;
&lt;li&gt;Before spending big $$$, take a short online course and learn the ins and outs of the platform. You don't want to be surprised afterwards.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  I hope you enjoyed this post! If you have subscribe to &lt;a href="https://bootstrapperstales.com/"&gt;my newsletter&lt;/a&gt; to be notified on future posts.
&lt;/h3&gt;

</description>
      <category>startup</category>
    </item>
    <item>
      <title>Tutorial: Add Forms to Static Sites with Google Sheets</title>
      <dc:creator>Bootstrapper's Tales</dc:creator>
      <pubDate>Sun, 02 May 2021 17:34:50 +0000</pubDate>
      <link>https://dev.to/bs_tales/tutorial-add-forms-to-static-sites-with-google-sheets-1c3a</link>
      <guid>https://dev.to/bs_tales/tutorial-add-forms-to-static-sites-with-google-sheets-1c3a</guid>
      <description>&lt;p&gt;&lt;strong&gt;Originally posted on &lt;a href="https://bootstrapperstales.com/forms-static-site-googlesheets?utm_source=devto" rel="noopener noreferrer"&gt;Bootstrapper's Tales&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I decided to add a guides section to the blog. The plan is simple - every time I spend too much time figuring something out, I'll write a guide about it.&lt;/p&gt;

&lt;p&gt;This guide is about how to create an HTML form that stores responses directly to a Google Sheet. It's how I set up the email sign-up form you see at the bottom of the page 👇👇👇 &lt;/p&gt;

&lt;p&gt;It's easy, requires no extra services, and takes around 10 minutes. The perfect solution to collect emails on a small static website. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Prepare the Google Sheet
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href=""&gt;Google Sheets&lt;/a&gt; and create a blank sheet&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Name it however you'd like. In the first row insert &lt;code&gt;timestamp&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; as headers&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fro9gz8r8l55bfqic3sd7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fro9gz8r8l55bfqic3sd7.png" title="Sheet Headers" alt="Sheet Headers"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the top bar, click on Tools &amp;gt; Script Editor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Name your script&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste the following code into &lt;code&gt;Code.gs&lt;/code&gt; (Override any code there)&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sheetName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sheet1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;scriptProp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PropertiesService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getScriptProperties&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;initialSetup&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;activeSpreadsheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SpreadsheetApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getActiveSpreadsheet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;scriptProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;activeSpreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doPost&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;LockService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getScriptLock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tryLock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SpreadsheetApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scriptProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSheetByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sheetName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLastColumn&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nextRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLastRow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;newRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextRow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValues&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;newRow&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ContentService&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTextOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;result&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nextRow&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMimeType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ContentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MimeType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ContentService&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTextOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;result&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMimeType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ContentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MimeType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;releaseLock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Save the script&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Setup and publish the project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; On the top, choose &lt;code&gt;initialSetup&lt;/code&gt; function and click run
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fulh3s69tlekdn6bcmpq9.png" title="Run initialSetup" alt="Run initialSetup"&gt;
&lt;/li&gt;
&lt;li&gt;Authorize the script with your Google Account&lt;/li&gt;
&lt;li&gt;On the left, click "Triggers" (clock icon) and then Add Trigger.&lt;/li&gt;
&lt;li&gt;Choose the following settings and click save&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F08h9eixg3linczp0fvlv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F08h9eixg3linczp0fvlv.png" title="Google Sheets Form Trigger" alt="Google Sheets Form Trigger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the top, click Deploy &amp;gt; new deployment&lt;/li&gt;
&lt;li&gt;Select type (cog-wheel icon) &amp;gt; Web app&lt;/li&gt;
&lt;li&gt;Insert description, choose "Execute as Me", set access to "Anyone" and finally hit deploy&lt;/li&gt;
&lt;li&gt;Take note of the web app URL that is provided on screen&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: add the form to your website
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add the code below to your website. Replace &lt;code&gt;YOUR_WEB_APP_URL&lt;/code&gt; with your web app URL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:center;"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"submit-to-google-sheet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email-submit"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Send&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scriptURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;YOUR_WEB_APP_URL&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forms&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit-to-google-sheet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;submit_button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button#email-submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;submit_button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sending...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scriptURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;submit_button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Done!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;submit_button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extras
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Add a Google Form fallback
&lt;/h3&gt;

&lt;p&gt;I'm not 100% sure what the capacity of this method is. Can it handle 1000 form submits (I wish 😅) within a minute?&lt;/p&gt;

&lt;p&gt;So, just to make sure, I implemented a fallback. In case of failure, my website opens a new tab with a Google Form to submit an email.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;a href=""&gt;Google From&lt;/a&gt; and set up the relevant questions (i.e. email)&lt;/li&gt;
&lt;li&gt;Add the following snippet when your post request fails. Replace &lt;code&gt;GOOGLE_FORM_LINK&lt;/code&gt; with the link to your form
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;window.open(GOOGLE_FORM_LINK);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;So all in all your html code should look like this
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form style="text-align:center;" name="submit-to-google-sheet"&amp;gt;
  &amp;lt;input name="email" type="email" placeholder="Email" required&amp;gt;
  &amp;lt;button id="email-submit" type="submit"&amp;gt;Send&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;script&amp;gt;
  const scriptURL = YOUR_WEB_APP_URL
  const form = document.forms['submit-to-google-sheet']

  form.addEventListener('submit', e =&amp;gt; {
    e.preventDefault()
    submit_button = document.querySelector("button#email-submit");
    submit_button.innerText = "Sending...";
    fetch(scriptURL, { method: 'POST', body: new FormData(form)})
      .then(function(response){
                console.log('Success!', response);
                submit_button.innerText = "Done!";
                })
      .catch(function(error) {
                console.error('Error!', error.message);
                submit_button.innerText = "Error!";
                window.open(GOOGLE_FORM_LINK);
                })
  })
&amp;lt;/script&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Collect more fields
&lt;/h3&gt;

&lt;p&gt;To capture more fields in your static site form, simply:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add headers to your Google Sheet&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; to your html form with a &lt;code&gt;name&lt;/code&gt; attribute that exactly matches your header. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, let's add first names. Your Google Sheet:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdbu9h9mqjuthvtua43q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdbu9h9mqjuthvtua43q.png" title="Google Sheet First Name" alt="Google Sheet First Name"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your HTML static form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form style="text-align:center;" name="submit-to-google-sheet"&amp;gt;
  &amp;lt;input name="email" type="email" placeholder="Email" required&amp;gt;
  &amp;lt;input name="first_name" type="text" placeholder="Your Name" required&amp;gt;
  &amp;lt;button id="email-submit" type="submit"&amp;gt;Send&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;I hope you enjoyed my guide! For more, follow me on &lt;a href="https://twitter.com/bs_tales" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or visit &lt;a href="http://bootstrapperstales.com" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;em&gt;adapted from &lt;a href="https://github.com/jamiewilson/form-to-google-sheets" rel="nofollow noopener noreferrer"&gt;jamiewilson&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>tutorial</category>
      <category>html</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
