<?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: Andy Kaiser</title>
    <description>The latest articles on DEV Community by Andy Kaiser (@andykaiser).</description>
    <link>https://dev.to/andykaiser</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%2F404314%2F46457467-3dc4-4a38-aaf9-33641b31b790.jpeg</url>
      <title>DEV Community: Andy Kaiser</title>
      <link>https://dev.to/andykaiser</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andykaiser"/>
    <language>en</language>
    <item>
      <title>Make Personalized Content Fast and Easier with Vercel Edge Functions and Ninetailed</title>
      <dc:creator>Andy Kaiser</dc:creator>
      <pubDate>Tue, 26 Oct 2021 16:40:13 +0000</pubDate>
      <link>https://dev.to/andykaiser/make-personalized-content-fast-and-easier-with-vercel-edge-functions-and-ninetailed-3cb9</link>
      <guid>https://dev.to/andykaiser/make-personalized-content-fast-and-easier-with-vercel-edge-functions-and-ninetailed-3cb9</guid>
      <description>&lt;p&gt;Before diving into the edge functions, let's start talking about edge computing and how we came to edge computing. &lt;/p&gt;

&lt;p&gt;For the last years, everyone is started talking about the edge. It became the next big thing after cloud, IoT, and blockchain.&lt;/p&gt;

&lt;p&gt;In the beginning, the first computers were big, isolated computers that people could only access directly. Then we had personal computers. Personal computers could do computing in a much more distributed manner. At that time, data was saved on a user's computer locally.&lt;/p&gt;

&lt;p&gt;Next, cloud computing came into our lives. &lt;a href="https://www.redhat.com/en/topics/cloud-computing/what-are-cloud-services" rel="noopener noreferrer"&gt;Cloud services&lt;/a&gt; are infrastructure, platforms, or software that are hosted by third-party providers and made available to users through the internet.&lt;/p&gt;

&lt;p&gt;However, due to the distance between clients and the data centers where cloud services are hosted, cloud computing can cause delays. For this reason, edge computing entered our lives.&lt;/p&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%2F0zmsrkt8uixbigzrtf5m.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%2F0zmsrkt8uixbigzrtf5m.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.cloudflare.com/en-gb/learning/serverless/glossary/what-is-edge-computing/" rel="noopener noreferrer"&gt;Edge computing&lt;/a&gt; is a networking philosophy focused on bringing computing as close to the source of data as possible in order to reduce latency and bandwidth use. In simpler terms, edge computing means running fewer processes in the cloud and moving those processes to local places, such as on a user's computer, an IoT device, or an edge server. Bringing computation to the network's edge minimizes the amount of long-distance communication that has to happen between a client and server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In summary:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;First Computing:&lt;/strong&gt; One centralized computer running applications and storing data locally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personal Computing:&lt;/strong&gt; Decentralized computers running applications and storing data locally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Computing:&lt;/strong&gt; Centralized computers running applications and storing data in data centers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge Computing:&lt;/strong&gt; Centralized computers running applications and storing data close to users - either on the device itself or on the network edge&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What are Edge Functions
&lt;/h2&gt;

&lt;p&gt;Edge Functions are the solution to bring edge computing to run JavaScript code at the edge before a request is processed, streamlining continuous delivery between backend developers and frontend developers to improve time to market.&lt;/p&gt;

&lt;p&gt;This enables development teams to more easily deliver a number of features such as A/B testing, custom authentication, dynamic routing, personalization, and more.&lt;/p&gt;

&lt;p&gt;Edge Functions are aimed to make the developer experience easier by allowing you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simplify experimentation&lt;/li&gt;
&lt;li&gt;customize authentication&lt;/li&gt;
&lt;li&gt;personalize web content&lt;/li&gt;
&lt;li&gt;enhance security&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Main Benefits of Edge Functions:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lower Latency
&lt;/h3&gt;

&lt;p&gt;Lower latency is the major benefit of edge functions when it comes to improving the overall performance of your products.&lt;/p&gt;

&lt;p&gt;Users of all web apps will experience delays when they face processes requiring communication with an external server. The length of these delays will vary depending on the server's available bandwidth and location, but they can be eliminated entirely by moving more operations to the edge.&lt;/p&gt;

&lt;p&gt;Because Edge Functions run on the content delivery network edge node closest to the user, they have lower latency than other options.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edge SEO
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://dantaylor.online/edge-seo/" rel="noopener noreferrer"&gt;Edge SEO&lt;/a&gt; is a field of technical SEO that utilizes serverless (edge) technologies to execute changes to code through using the CDN as a form of middle-ground in which SEO hotfixes and recommendations can be implemented. These changes are agnostic of the website infrastructure (origin source code) and are supported by multiple CDNs through "edge functions" technology.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As it's described earlier, edge functions close the gap between the user and the data source. &lt;/p&gt;

&lt;p&gt;Using the edge functions in the website will bring a couple of benefits, such as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;speed&lt;/li&gt;
&lt;li&gt;improved site security&lt;/li&gt;
&lt;li&gt;possibility to perform A/B testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use Cases for Edge Functions
&lt;/h2&gt;

&lt;p&gt;Basically, you can do anything and everything with edge functions. Since you'll be writing code, possibilities will be infinite. Here are just a few use cases for edge functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Experimentation:&lt;/strong&gt; Use edge functions to process and analyze customers' data at the edge in real-time. ****&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personalization:&lt;/strong&gt; Increase conversion rates by delivering content that automatically tailors based on each user's location and other signals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Distribute your data across the edge locations with edge functions to distribute and reduce the risk as well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication:&lt;/strong&gt; Deliver fast authentication with edge functions by caching and verifying credentials at the edge.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Personalization With Vercel Edge Functions and Ninetailed
&lt;/h2&gt;

&lt;p&gt;Ninetailed is an &lt;a href="https://ninetailed.io" rel="noopener noreferrer"&gt;API-first optimization platform&lt;/a&gt; that works with Contentful and other headless CMS platforms. It includes SDKs for Next.js and Vercel Edge Functions to make it simple to integrate personalization on the edge.&lt;/p&gt;

&lt;p&gt;This short guideline walks you through setting up and integrating Ninetailed and Next.js with Edge Functions. In this guide, you'll find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to install the SDK for Next.js with Edge Functions&lt;/li&gt;
&lt;li&gt;Steps you need to follow to personalize components in Next.js&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Install Ninetailed SDKs for Next.js and Edge Functions
&lt;/h3&gt;

&lt;p&gt;With the Next.js SDK, you can add dynamic content for personalization to any component. In this step, you need to install Ninetailed SDKs for Next.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install module via yarn:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ninetailed&lt;/span&gt;&lt;span class="sr"&gt;/experience-sdk-nextjs @ninetailed/&lt;/span&gt;&lt;span class="nx"&gt;experience&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sdk&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;nextjs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ssr&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ninetailed&lt;/span&gt;&lt;span class="sr"&gt;/experience-sdk-nextjs-es&lt;/span&gt;&lt;span class="err"&gt;r
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2. Add Ninetailed to the middleware
&lt;/h3&gt;

&lt;p&gt;In the folder pages add the SDKs to the &lt;code&gt;_middleware.ts&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EdgeRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EdgeResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;NinetailedPersonalizationMiddleware&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ninetailed/experience-sdk-nextjs-esr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Add the Personalization Middleware&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EdgeRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EdgeResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nc"&gt;NinetailedPersonalizationMiddleware&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NINETAILED_API_KEY&lt;/span&gt; &lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;h3&gt;
  
  
  Step 3. Add Ninetailed to the app
&lt;/h3&gt;

&lt;p&gt;Now, in the same folder, let's add the SDKs to the &lt;code&gt;app.ts&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;PersonalizationProvider&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ninetailed/experience-sdk-nextjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ninetailedSSRTrackerPlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ninetailed/experience-sdk-ssr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;selectNinetailedProfile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ninetailed/experience-sdk-nextjs-esr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Add the Personalization Provider&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AppProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;selectNinetailedProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PersonalizationProvider&lt;/span&gt;
&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ninetailedSSRTrackerPlugin&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NINETAILED_API_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;PersonalizationProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Steps
&lt;/h3&gt;

&lt;p&gt;In the documentation of Ninetailed, you can also find a more detailed &lt;em&gt;&lt;a href="https://docs.ninetailed.io/getting-started/quick-start-for-developers-next" rel="noopener noreferrer"&gt;Quick Start Guide for Developers&lt;/a&gt;&lt;/em&gt; with additional steps such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to &lt;a href="https://docs.ninetailed.io/cms/contentful/installation" rel="noopener noreferrer"&gt;set up Ninetailed App on Contentful&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to use Ninetailed &lt;a href="https://docs.ninetailed.io/frameworks/next/profile" rel="noopener noreferrer"&gt;Profiles in Next.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to integrate &lt;a href="https://docs.ninetailed.io/integrations/google-analytics" rel="noopener noreferrer"&gt;Google Analytics with Ninetailed&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Vercel Edge Functions provide a completely new way to run JavaScript code at the edge prior to processing a request. They make it easier to deliver features like A/B testing, custom authentication, dynamic routing, and personalization without affecting latency, improving the web core vitals and SEO.&lt;/p&gt;

&lt;p&gt;This is why personalization on the edge with Edge Functions and Ninetailed is the way to go to create personalized experiences and improve the overall user experience and SEO.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>nextjs</category>
      <category>webperf</category>
    </item>
    <item>
      <title>What I have learned of building a chatbot in GatsbyJS, Contentful and Ninetailed
</title>
      <dc:creator>Andy Kaiser</dc:creator>
      <pubDate>Tue, 06 Apr 2021 12:32:34 +0000</pubDate>
      <link>https://dev.to/andykaiser/what-i-have-learned-of-building-a-chatbot-in-gatsbyjs-contentful-and-ninetailed-3hdi</link>
      <guid>https://dev.to/andykaiser/what-i-have-learned-of-building-a-chatbot-in-gatsbyjs-contentful-and-ninetailed-3hdi</guid>
      <description>&lt;p&gt;To begin with, building a Chatbot with &lt;a href="https://www.gatsbyjs.com/"&gt;GatsbyS&lt;/a&gt; and &lt;a href="https://www.contentful.com/"&gt;Contentful&lt;/a&gt; may appear strange, but it all began with a customer personalization exercise and experiment at my company &lt;a href="https://www.ninetailed.io/"&gt;Ninetailed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And, spoiler alert, our GatsbyJS, Contentful, and Ninetailed based Chatbot works great and, more importantly, it was fun and quick to develop (we finished it in a couple of hours).&lt;/p&gt;

&lt;h2&gt;
  
  
  GatsbyJS, Contentful &amp;amp; Ninetailed - An Introduction
&lt;/h2&gt;

&lt;p&gt;We use GatsbyJS for our website ninetailed.io because it is great for creating lightning-fast, accessible, and SEO-friendly websites. It is also easy to use and integrates seamlessly with our headless CMS Contentful.&lt;/p&gt;

&lt;p&gt;Ninetailed, on the other hand, is a personalization and optimization platform for modern websites. Not to mention that Ninetailed has a &lt;a href="https://www.gatsbyjs.com/plugins/@ninetailed/gatsby-plugin-ninetailed/"&gt;GatbsyJS plugin&lt;/a&gt; and a &lt;a href="https://www.contentful.com/marketplace/app/ninetailed-personalization"&gt;Contentful App&lt;/a&gt; to make integration in this stack simple and quick.&lt;br&gt;
Personalizing our website with a Chatbot&lt;/p&gt;

&lt;p&gt;We had the idea to integrate a chatbot with the Ninetailed personalization platform during a brainstorming session about personalization experiences. An interactive chatbot is ideal for gathering information from visitors such as intent, job roles, and adapting website content to user data and intent. As a result, the content journey and customer experience are enhanced.&lt;/p&gt;

&lt;p&gt;The next step is to select a Chatbot solution. There are numerous advanced Chatbot solutions available, such as Solvemate or Intercom, that combine the power of natural language processing (NLP), rule-based conversations, and human operators.&lt;/p&gt;

&lt;p&gt;Following our API-first, rapid prototyping, and agile development philosophy, we decided to create a prototype using our personalization API and SDKs. After all, we want to personalize our website based on visitor intent, and our personalization engine can handle rule-based audiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's build a chatbot
&lt;/h2&gt;

&lt;p&gt;For our website stack we use GatsbyJs, Contentful, Tailwind CSS and Ninetailed for website personalization. This stack will serve as our starting point...&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Chatbot flow
&lt;/h3&gt;

&lt;p&gt;First and foremost, we define the chatbot flow. We keep things simple because we're working on a prototype. In this first iteration, we use a decision tree model with two steps and two data points or user traits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first step is to request the first name in order to personalize the page and create a demo effect. This also personalizes the guide experience, and we want to highlight our merge tag personalization feature.&lt;/li&gt;
&lt;li&gt;The second step is to inquire about the visitor's role. This allows us to match the visitor to one of our personas and adapt the website's content. The role is an important aspect of our marketing personas, as it relates to the visitor's intent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B7RxTLpG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bl5xritmkk8v3ducm1ke.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B7RxTLpG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bl5xritmkk8v3ducm1ke.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
Chatbot flow



&lt;h3&gt;
  
  
  2. Chatbot UI
&lt;/h3&gt;

&lt;p&gt;Because we use Tailwind UI as design system, creating chatbot UI elements like the bubble and chat window is simple and quick.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MmpJgsTA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f87x8i8bn7x5m0mtk68d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MmpJgsTA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f87x8i8bn7x5m0mtk68d.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
Chatbot UI example



&lt;h3&gt;
  
  
  3. Contentful content model
&lt;/h3&gt;

&lt;p&gt;We create a new content model in Contentful with the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name used as entry title.&lt;/li&gt;
&lt;li&gt;Image for the chatbot&lt;/li&gt;
&lt;li&gt;Message for the chatbot.&lt;/li&gt;
&lt;li&gt;Placeholder for the input field.&lt;/li&gt;
&lt;li&gt;Button text for the button.&lt;/li&gt;
&lt;li&gt;Event ID to define the event to send with the value of the input. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have a lot of flexibility with this content structure because we can create the chatbot content within Contentful CMS without changing any code and adapt the content variants for personalization with the Ninetailed Personalization App.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Ninetailed personalization
&lt;/h3&gt;

&lt;p&gt;Finally, integrating the code with Ninetaled takes only a few minutes because we only need to wrap the chat component with the &lt;code&gt;&amp;lt;Personalize /&amp;gt;&lt;/code&gt; component (and install the GatbsyJS plugin if you haven't already).&lt;/p&gt;

&lt;h4&gt;
  
  
  Chatbot component code example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChatFragment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../@generated/types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChatApiProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./ChatApiProvider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Body&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Launcher&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Launcher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Chat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ChatFragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ChatApiProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Launcher&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Container&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ChatApiProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;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;h4&gt;
  
  
  Ninetailed personalization code example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GatsbyImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getImage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby-plugin-image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&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="nx"&gt;Field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-final-form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nx"&gt;useAnalytics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nx"&gt;useProfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ninetailed/client-sdk-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRenderNinetailedMergetag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ninetailed/client-sdk-gatsby-contentful&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BLOCKS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;INLINES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MARKS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@contentful/rich-text-types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@contentful/rich-text-react-renderer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;GatsbyLink&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChatFragment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../@generated/types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderRichText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../RichText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sanitizeSlug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../Link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useChatApi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./ChatApiProvider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CloseButton&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./CloseButton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
 &lt;span class="na"&gt;renderNode&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="nx"&gt;BLOCKS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PARAGRAPH&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-sm text-gray-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;INLINES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HYPERLINK&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
       &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
       &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-indigo-600 hover:text-indigo-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
     &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;INLINES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ENTRY_HYPERLINK&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GatsbyLink&lt;/span&gt;
       &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sanitizeSlug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
       &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-medium text-indigo-600 hover:text-indigo-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
     &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/GatsbyLink&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;INLINES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EMBEDDED_ENTRY&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__typename&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ContentfulLink&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
         &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt;
           &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inline-flex my-2 mr-2 items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
           &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mr-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createRenderNinetailedMergetag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="nx"&gt;INLINES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EMBEDDED_ENTRY&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;
           &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="nx"&gt;children&lt;/span&gt;
         &lt;span class="p"&gt;)}&lt;/span&gt;
       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;     &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Variants and audiences
&lt;/h3&gt;

&lt;p&gt;In Contentful, we must now create variants and specific audiences for the chatbot content. It only takes a few clicks to create personalization variants with Ninetailed and Contentful. If the visitor has filled out a first name and has chosen a role in the chatbot, we create a variant for the chat message.&lt;/p&gt;

&lt;p&gt;We use user traits and events for the audiences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visitors who have filled out their first names.&lt;/li&gt;
&lt;li&gt;Visitors who have chosen a role.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y-rUZOEc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wlna1mt10nfzpttteqzv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y-rUZOEc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wlna1mt10nfzpttteqzv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
Audience first name



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--60TjRha---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gg19n3w1q5ylwm6od83f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--60TjRha---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gg19n3w1q5ylwm6od83f.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
Audience developers



&lt;h2&gt;
  
  
  Learnings and next steps
&lt;/h2&gt;

&lt;p&gt;This chatbot integration took us only a few hours to complete. It was not only quick to make, but also enjoyable to work on. This prototype project demonstrated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working with your own stack and product must be exciting.&lt;/li&gt;
&lt;li&gt;Think outside the box and be inventive in the application of your own product.&lt;/li&gt;
&lt;li&gt;Developer experience with your stack and tools is critical.
GatbsyJS, Contentful and Ninetailed have an excellent developer experience.&lt;/li&gt;
&lt;li&gt;A design system enables rapid prototyping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As the prototype was successful in development, and after a week, the chatbot's engagement rates are great, we intend to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add more steps to the chatbot flow.&lt;/li&gt;
&lt;li&gt;Integrate more powerful chatbots.&lt;/li&gt;
&lt;li&gt;Create SDKs or integrations with chatbots.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, please let me know what you think about this chatbot prototype and how we used GatsbyJS, Contentful, and Ninetailed to create it. If you want to create a similar chatbot or customize your Contentful website with personalized content, you can install the Ninetailed app for free from the &lt;a href="https://www.contentful.com/marketplace/app/ninetailed-personalization"&gt;official marketplace&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>personalization</category>
      <category>cms</category>
    </item>
    <item>
      <title>Web Performance: a look at awareness in tech roles</title>
      <dc:creator>Andy Kaiser</dc:creator>
      <pubDate>Wed, 29 Jul 2020 10:12:32 +0000</pubDate>
      <link>https://dev.to/andykaiser/web-performance-a-look-at-awareness-in-tech-roles-4lda</link>
      <guid>https://dev.to/andykaiser/web-performance-a-look-at-awareness-in-tech-roles-4lda</guid>
      <description>&lt;h2&gt;
  
  
  Initial approach: why this research?
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://ninetailed.io"&gt;Ninetailed&lt;/a&gt; our main purpose is to improve the user experience and help other companies with it. We are also web performance junkies and are obsessed with persistently improving our service performance in the region of milliseconds.&lt;/p&gt;

&lt;p&gt;As marketeers, developers and product managers we abuse the usage of tag managers and third-party scripts. Using external scripts has a data value, but also an adverse consequence: poorer web performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our hypothesis
&lt;/h3&gt;

&lt;p&gt;Our hypothesis is that developers care more about web performance than other digital roles like marketeers and that they consider third-party scripts as an issue for the performance of their websites.&lt;/p&gt;

&lt;h3&gt;
  
  
  We believe that
&lt;/h3&gt;

&lt;p&gt;We believe that awareness around third-party scripts performance and the impact on the user experience is the first step for multidisciplinary teams to develop optimization strategies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;At the date of the analysis, the survey has 185 answers after promoting it to developers, product managers and marketeers in our professional network and in different Facebook, LinkedIn and Slack groups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Participants
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Roles
&lt;/h4&gt;

&lt;p&gt;Most of the participants are developers (51%), followed by marketeers (21%) and product managers (12%).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--17RpvBda--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bj2kgdd81tg1hvkpkepw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--17RpvBda--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bj2kgdd81tg1hvkpkepw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Company size
&lt;/h4&gt;

&lt;p&gt;The survey has participants from SMB and also corporations with more than 500 employees. Most of participants work in companies up to 50 employees (70%).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Oxd1fBVv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fpj65rjf57uxw86nknfc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Oxd1fBVv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fpj65rjf57uxw86nknfc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The answers
&lt;/h3&gt;

&lt;p&gt;The main questions of the survey ask how much do the participants agree with a statement. The responses are based on &lt;a href="https://en.wikipedia.org/wiki/Likert_scale"&gt;Likert Scale&lt;/a&gt;, from “Strongly disagree” (score 1) to “Strongly agree” (score 5).&lt;/p&gt;

&lt;p&gt;The survey questions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web performance has a positive impact on the user experience.&lt;/li&gt;
&lt;li&gt;Web performance has a positive impact on SEO.&lt;/li&gt;
&lt;li&gt;Third-party scripts harm website performance.&lt;/li&gt;
&lt;li&gt;Ad Blockers harm website analytics.&lt;/li&gt;
&lt;li&gt;Ad Blockers are an issue for me.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y5KeQwMD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xobatxrku005eu9dczod.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y5KeQwMD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xobatxrku005eu9dczod.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The participants strongly agree that performance plays a major role in a good user experience (avg. 4,6) and benefits SEO (avg. 4,5). Most of the respondents agree that third-party scripts are an issue (avg. 4,1). Regarding Ad Blockers, the respondents are neutral, and do not agree nor disagree if Ad Blockers affect their analytics or if they are an issue for them.&lt;/p&gt;

&lt;p&gt;Analyzing the responses based on the role we see some minor differences.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--51fjkyPg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mclrktip08obaomkohmv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--51fjkyPg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mclrktip08obaomkohmv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Buh4CCw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6r3mo2d65uodfp4wlttl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Buh4CCw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6r3mo2d65uodfp4wlttl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BmmW9Op8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l9zwa21cg0x3an97ij58.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BmmW9Op8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l9zwa21cg0x3an97ij58.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The three groups agree that performance has a positive impact in UX and SEO. They also agree that external scripts harm web performance. Marketeers agree most that Ad Blockers harm the website analytics, compared to developers which are neutral and product managers that disagree.&lt;/p&gt;

&lt;h4&gt;
  
  
  Frameworks and Tag Managers
&lt;/h4&gt;

&lt;p&gt;Finally, 49% of the respondents use a Tag Manager. 62% use a CMS, 22% a Single Page Application and 5% a static site or static site generator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M3MDGP9E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a0pa4kdn9e1tqze87qss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M3MDGP9E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a0pa4kdn9e1tqze87qss.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QJ7rWOci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/71bk6g1gfie84hx8h6i0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QJ7rWOci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/71bk6g1gfie84hx8h6i0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Not only developers care about performance. The main digital roles which are responsible for a website strongly agree that performance has a positive impact on the user experience and SEO. They also agree that third-party scripts harm the performance and are neutral about Ad Blockers and the impact on website analytics.&lt;/p&gt;

&lt;p&gt;Even if there is awareness about performance, the usage of external scripts &lt;a href="https://httparchive.org/reports/state-of-javascript?start=2016_09_01&amp;amp;end=latest&amp;amp;view=list"&gt;grows every year&lt;/a&gt;. Without more details, we cannot say if this is based on a cost-benefit analysis or the data-needs to optimize the user experience and business goals.&lt;/p&gt;

&lt;p&gt;For future surveys we should explore the solutions and efforts put into improving performance and the reasons behind a neutral position towards the impact of Ad Blockers in website analytics and the data-based decision process.&lt;/p&gt;

&lt;p&gt;What do you think about these results? Let me know in the comments!&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://ninetailed.io/blog/web-performance-research/"&gt;ninetailed.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webperf</category>
      <category>webdev</category>
      <category>survey</category>
      <category>devops</category>
    </item>
    <item>
      <title>Web performance &amp; Ad-blockers survey</title>
      <dc:creator>Andy Kaiser</dc:creator>
      <pubDate>Tue, 09 Jun 2020 15:13:12 +0000</pubDate>
      <link>https://dev.to/andykaiser/web-performance-ad-blockers-survey-5ac9</link>
      <guid>https://dev.to/andykaiser/web-performance-ad-blockers-survey-5ac9</guid>
      <description>&lt;p&gt;&lt;em&gt;"Optimizing for quality of user experience is key to the long-term success of any site on the web."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/vitals/"&gt;Web Vitals&lt;/a&gt; is an initiative by Google to provide unified guidance for quality signals that are essential to delivering a great user experience on the web.&lt;/p&gt;

&lt;p&gt;I'm conducting a research about website performance, Ad-blockers and user experience. This will help us to understand the importance of optimizing 3rd party scripts and Ad-blockers effect on websites to improve the user experience.&lt;/p&gt;

&lt;p&gt;I would appreciate if you take about 2 minutes of your time to share your thoughts about it. Thank you for taking my quick survey!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forms.gle/b1CKYH9gzKnsFuUT9"&gt;https://forms.gle/b1CKYH9gzKnsFuUT9&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>survey</category>
      <category>webperf</category>
      <category>privacy</category>
    </item>
  </channel>
</rss>
