{"id":101818,"date":"2024-03-21T00:24:18","date_gmt":"2024-03-21T00:24:18","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=101818"},"modified":"2024-03-25T15:48:56","modified_gmt":"2024-03-25T15:48:56","slug":"cloudfare-turnstile-a-new-way-to-prove-you-are-real","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/web\/cloudfare-turnstile-a-new-way-to-prove-you-are-real\/","title":{"rendered":"Cloudfare Turnstile, A New Way To Prove You Are Real"},"content":{"rendered":"<p><em>\u00a0 \u00a0 This article describes the recommended way to integrate Cloudflare Turnstile into a React application.<\/em><\/p>\n<p>When I first heard about Cloudflare Turnstile, I remembered the New York City subway entrances. After all, I have been commuting with the subway for over ten years and can\u2019t even count how many turnstiles there would ever be.<\/p>\n<p>CAPTCHAs are probably the most hated things on the internet. How often were you tired of clicking those traffic lights and motorcycles? I know I hate them. I am almost sure that you do, too. Even though we all know this, as developers, we sometimes have to show CAPTCHA in front of a user. We need our applications to be secure and keep the bots away, right? We didn\u2019t have any better alternatives until just recently.<\/p>\n<p>A single CAPTCHA takes 32 seconds to complete on average. Given 4.6 Billion global internet users see a CAPTCHA every ten days, would equate to 500 human years wasted every single day. This madness has to stop. Cloudflare can reduce the average verification time to about a second. A substantial reduction from 32 seconds<\/p>\n<h2><a id=\"post-101818-X94731732e24633837ce0e00c1b4d43d3f89236b\"><\/a>Cloudflare Turnstile to rescue! Drum roll, please \ud83e\udd41\ud83e\udd41\ud83e\udd41<\/h2>\n<p>Cloudflare Turnstile is a free, tool to replace the dreaded CAPTCHAs. Why is the hype? How are they different? Let\u2019s dive a little deeper.<\/p>\n<p>In order to distinguish bots from humans, turnstile checks for typical human behavior in the browser by running non-interactive javascript challenges. Turnstile uses the results of these challenges to make its judgement to identify bots from humans.<\/p>\n<p>How would this help us, the ReactJS developers? Let\u2019s dive into that.<\/p>\n<h2><a id=\"post-101818-turnstile-in-reactjs-and-nextjs\"><\/a>Turnstile in ReactJS and NextJS<\/h2>\n<p>This Turnstile team has released different integration libraries for popular front-end frameworks. For <a href=\"https:\/\/react.dev\/\">ReactJS<\/a>, the recommended approach from Cloudflare is to use open-source libraries such as <a href=\"https:\/\/www.npmjs.com\/package\/@marsidev\/react-turnstile\">react-turnstile<\/a>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"592\" height=\"124\" class=\"wp-image-101819\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/turnstile_action.png\" alt=\"turnstile_action\" \/><\/p>\n<p>Turnstile is a powerful tool for production websites. Since for the rest of the blog, we need an easy ReactJS framework to deploy a test website and turn on Turnstile; we will be using NextJS. Don\u2019t worry; Turnstile works equally well on vanilla ReactJS as well; the addition of NextJS is only for easy deployment to Vercel, nothing more.<\/p>\n<h2><a id=\"post-101818-create-a-react-app-with-nextjs.\"><\/a>Create a React App with NextJS.<\/h2>\n<pre class=\"lang:c# theme:vs2012\">$ npx create-next-app@latest<\/pre>\n<p>This is a standard npx command you can run from your Terminal (If you have VS Code, use its Terminal). Make sure you are in the folder you want your application to be housed in before running this command. For our purposes, you will likely want to make sure you are running this command in the root directory for your github configuration (certainly for the easiest setup. This will create a directory that matches your project name that you will be checking in.<\/p>\n<p>Choosing the default can\u2019t be wrong here. After all, we are focused on Turnstile, not NextJS..<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"953\" height=\"1003\" class=\"wp-image-101820\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/a-screenshot-of-a-computer-program-description-au.png\" alt=\"A screenshot of a computer program\n\nDescription automatically generated\" \/><\/p>\n<p>Please see the highlighted \u2018project name\u2019 in the picture above. <code>npx <\/code>command will create a folder with this name. Make sure to move to that folder using the below command <code>cd .\\turnstile-react-nextjs\\.<\/code> This will be the root folder of your newly created application.<\/p>\n<p>Test your app quickly using <code>npx next dev<\/code> in the context of the base folder for the project (In above example, it is <code>C:\\Code\\turnstile-react-nextjs&gt;<\/code>)<\/p>\n<p>Once the command finishes executing, you should see something very similar to the next images when you go to <code>http:\/\/localhost:3000<\/code> in your browser.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1155\" height=\"812\" class=\"wp-image-101821\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/home-default.png\" alt=\"home-default\" \/><\/p>\n<h2><a id=\"post-101818-deploy-with-vercel\"><\/a>Deploy our new NextJS application to a public domain with Vercel<\/h2>\n<p>We need an actual website to create a <code>siteKey<\/code> for Cloudflare (We need this for complete configuration). The best bet for us is Vercel. It is from the same team as NextJS, and basic deployments to a public vercel subdomain are free. So, how about we deploy the website we just built?<\/p>\n<p>We will not be getting to the nitty-gritty of Vercel deployments, but we will use the seamless integration by Vercel to Github to connect Vercel to our codebase. Connected a Github repository to Vercel is available on Vercel\u2019s home page after logging in using Github credentials.<\/p>\n<ul>\n<li>Push the source code of your newly created NextJS app to a repository in a Git provider such as Github. For Github, follow these steps to push your source code into a new repository &#8211; <a href=\"https:\/\/docs.github.com\/en\/repositories\/creating-and-managing-repositories\/creating-a-new-repository\">https:\/\/docs.github.com\/en\/repositories\/creating-and-managing-repositories\/creating-a-new-repository<\/a>.<\/li>\n<li>For vercel to identify our NextJS project, the project\u2019s source code should be at the root of the repository as shown below.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1618\" height=\"875\" class=\"wp-image-101822\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/a-screenshot-of-a-computer-description-automatica-20.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<ul>\n<li>Go to <a href=\"https:\/\/vercel.com\/new\">https:\/\/vercel.com\/new<\/a> (Create a new Vercel account or log in with your existing credentials when prompted).<\/li>\n<li>Vercel should have permissions to access the repository. To provide access, choose \u201cAdjust Github App Permissions -&gt;\u201d link. This will allow you to connect Vercel to your repo. On the configuration pop-up, Select your new repository under \u2018Repository access\u2019 and click \u2018Save\u2019<\/li>\n<li><strong>Now, using the \u2018import\u2019 button, import your repo into Vercel as shown below. With this step, you are ready to deploy. <\/strong><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1257\" height=\"722\" class=\"wp-image-101823\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/vercel-github-repo-select.png\" alt=\"vercel-github-repo-select\" \/><\/p>\n<ul>\n<li><strong>Connect the Github repo<\/strong><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1919\" height=\"948\" class=\"wp-image-101824\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/vercel-github-repo-connect.png\" alt=\"vercel-github-repo-connect\" \/><\/p>\n<ul>\n<li><strong>The Deploy Step <\/strong>&#8211; Select &#8216;Netx.js&#8217; from the Framework Preset dropdown, then click &#8216;Deploy&#8217; and&#8230;<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1260\" height=\"741\" class=\"wp-image-101825\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/vercel-deploy.png\" alt=\"vercel-deploy\" \/><\/p>\n<ul>\n<li><strong>That\u2019s it! &#8211; <\/strong>Now, if we push the code to our Github repo, Vercel will take care of deploying it. Auto-magically!<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1255\" height=\"626\" class=\"wp-image-101826\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/vercel-deployed.png\" alt=\"vercel-deployed\" \/><\/p>\n<ul>\n<li><strong>Our website is up <\/strong>Look at the URL!<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"1026\" class=\"wp-image-101827\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/website.png\" alt=\"website\" \/><\/p>\n<h2><a id=\"post-101818-cloudflare-turnstile-configurations\"><\/a>Cloudflare Turnstile Configurations<\/h2>\n<p>It is time to configure Turnstile and generate a <code>siteKey<\/code>. We will later marry this <code>siteKey<\/code> to the web app we just deployed.<\/p>\n<p>As the first step, log in to Cloudflare.com. Select Turnstile from the left navigation menu on your dashboard and click the \u2018<strong>Add site<\/strong>\u2019 button.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1495\" height=\"728\" class=\"wp-image-101828\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/turnstile-addsite.png\" alt=\"turnstile-addsite\" \/><\/p>\n<p>The next screen is where we connect the web app we just deployed with Turnstile. Enter our website\u2019s domain\/subdomain name(Did you see? This is where we let Turnstile know who we are and we are real) and press \u2018Create\u2019.<\/p>\n<p>Copy the <code>Site<\/code> Key and <code>Secret Key<\/code> from the generated screen. We need these keys later.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"878\" height=\"768\" class=\"wp-image-101829\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/add-site.png\" alt=\"add-site\" \/><\/p>\n<h2><a id=\"post-101818-setup-turnstile-in-our-nextjsreact-app.\"><\/a>Setup Turnstile in our NextJS\/React App.<\/h2>\n<p><strong><em>Install Turnstile<\/em><\/strong><\/p>\n<p>The Turnstile team recommends two major packages <a href=\"https:\/\/www.npmjs.com\/package\/@marsidev\/react-turnstile\">@marsidev\/react-turnstile<\/a> and <a href=\"https:\/\/www.npmjs.com\/package\/react-turnstile\">react-turnstile<\/a>. Both have similar configurations. For this article, we will use <a href=\"https:\/\/www.npmjs.com\/package\/@marsidev\/react-turnstile\">@marsidev\/react-turnstile<\/a>.<\/p>\n<p>Install the package like this.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">npm i @marsidev\/react-turnstile<\/pre>\n<p><strong><em>Add turnstile into a form.<\/em><\/strong><\/p>\n<p>Now that Turnstile is installed let\u2019s protect a login form using that. First, let\u2019s remove all the content of src\\app\\page.tsx and insert the following code. After inserting the code, replace the Site Key from Cloudfare in the locations in the code where it is requested.<\/p>\n<pre class=\"lang:c# theme:vs2012\">'use client';\r\nimport { useRef, useState } from 'react';\r\nimport styles from '.\/page.module.css'\r\nimport { Turnstile, TurnstileInstance } from '@marsidev\/react-turnstile'; \/\/ &lt;------------- Importing Turnstile component\r\n\r\nconst Home = () =&gt; {\r\n\r\n  const [canSubmit, setCanSubmit] = useState(false); \/\/ &lt;------------- We will use this state to enable submit button if Turnstile says all is well.\r\n  const refTurnstile = useRef&lt;TurnstileInstance&gt;(null); \/\/ &lt;------------- Ref to Turnstile component. We will use this to reset Turnstile after each submit.\r\n\r\n  const handleSubmit = async () =&gt; {\r\n    refTurnstile.current?.reset(); \/\/ &lt;------------- After each submit, recycling turnstile for next usage.\r\n    console.log('submitted!');\r\n  }\r\n\r\n  return (\r\n    &lt;div className={styles.pageCenter}&gt;\r\n      &lt;form onSubmit={handleSubmit}&gt;\r\n        &lt;div&gt;&lt;input type=\"text\" placeholder=\"username\" \/&gt;&lt;\/div&gt;\r\n        &lt;div&gt;&lt;input type=\"password\" placeholder=\"password\" \/&gt;&lt;\/div&gt;\r\n        &lt;div&gt;&lt;button type='submit' disabled={!canSubmit}&gt;Login&lt;\/button&gt;&lt;\/div&gt;\r\n        &lt;br \/&gt;\r\n        &lt;Turnstile\r\n          id='turnstile-1'\r\n          ref={refTurnstile}\r\n          siteKey='YOUR_SITE_KEY'\r\n          onSuccess={() =&gt; setCanSubmit(true)}\r\n        \/&gt;\r\n      &lt;\/form&gt;\r\n    &lt;\/div&gt;\r\n  )\r\n}\r\n\r\nexport default Home;<\/pre>\n<p>Now, just push the changes to your git repository. Vercel should take care of auto-deployment. Check your site after deployment, Viola! The turnstile is set up and ready to go.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"639\" height=\"495\" class=\"wp-image-101830\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/turnstile-in-action.png\" alt=\"turnstile-in-action\" \/><\/p>\n<p>The styling of the buttons and inputs is done through some quick CSS. A link to this entire project on GitHub is available towards the end of this article.<\/p>\n<p><strong><em>What is in the source code<\/em><\/strong><\/p>\n<p>The source code is quite self-explanatory, yet we will go through some of the corners.<\/p>\n<pre class=\"lang:c# theme:vs2012\">import { Turnstile, TurnstileInstance } from '@marsidev\/react-turnstile';<\/pre>\n<p>We are importing Turnstile here.<\/p>\n<pre class=\"lang:c# theme:vs2012\">const [canSubmit, setCanSubmit] = useState(false);\r\n.....\r\n&lt;button type='submit' disabled={!canSubmit}&gt;Login&lt;\/button&gt;\r\n.....\r\n&lt;Turnstile\r\n  siteKey='YOUR_SITE_KEY'\r\n  onSuccess={() =&gt; setCanSubmit(true)}\r\n\/&gt;<\/pre>\n<p>We ensure the login button stays disabled until Turnstile gives us a green signal.<\/p>\n<pre class=\"lang:c# theme:vs2012\">const refTurnstile = useRef&lt;TurnstileInstance&gt;(null);\r\n.....\r\nconst handleSubmit = async () =&gt; {\r\n  refTurnstile.current?.reset();\r\n}\r\n.....\r\n&lt;Turnstile\r\n  ref={refTurnstile}\r\n  siteKey='YOUR_SITE_KEY'\r\n  onSuccess={() =&gt; setCanSubmit(true)}\r\n\/&gt;<\/pre>\n<p>Here, we are keeping a ref to the Turnstile widget and asking it to reset after we submit a form.<\/p>\n<p>Turnstile is configurable to your needs of language, size, and theme. What if you need a smaller \u2018dark\u2019 themed widget in French? You got it with the code below. You can do many more fine-tuning on this widget for your needs.<\/p>\n<pre class=\"lang:c# theme:vs2012\"> &lt;Turnstile siteKey='YOUR_SITE_KEY'\r\n  options={{\r\n    theme: 'dark',\r\n    size: 'compact',\r\n    language: 'fr',\r\n  }}\r\n\/&gt;<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"533\" height=\"721\" class=\"wp-image-101831\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/03\/turnstile_action_french.png\" alt=\"turnstile_action_french\" \/><\/p>\n<p>Now, that\u2019s it. You have built a react + next web app, deployed it using Vercel, connected our website with Cloudflare Turnstile, and finally wrote some code to ensure it all works. I have uploaded the source code for this article <a href=\"https:\/\/github.com\/codehippie1\/turnstile-react-nextjs\">here<\/a>. Clone it, change the <code>siteKey<\/code>, and you are good to go.<\/p>\n<h2><a id=\"post-101818-wrap-up\"><\/a>Wrap up<\/h2>\n<p>Cloudflare Turnstile is a powerful tool that helps us secure web applications without making our users pull all their hair. It is in the news that bots solve CAPTCHAs better than humans lately. Turnstile is here to stay. Packages like <code>react-turnstile<\/code> wrap away much of the implementation details and help us integrate Turnstile into our code with few lines. Welcome to a new world without a million traffic lights!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0 \u00a0 This article describes the recommended way to integrate Cloudflare Turnstile into a React application. When I first heard about Cloudflare Turnstile, I remembered the New York City subway entrances. After all, I have been commuting with the subway for over ten years and can\u2019t even count how many turnstiles there would ever be&#8230;.&hellip;<\/p>\n","protected":false},"author":339718,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,147005],"tags":[159073],"coauthors":[146982],"class_list":["post-101818","post","type-post","status-publish","format-standard","hentry","category-featured","category-web","tag-web"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/101818","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/339718"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=101818"}],"version-history":[{"count":4,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/101818\/revisions"}],"predecessor-version":[{"id":101836,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/101818\/revisions\/101836"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=101818"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=101818"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=101818"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=101818"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}