<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ analytics - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ analytics - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 16:27:26 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/analytics/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Your Own Google Analytics Alternative Using Umami ]]>
                </title>
                <description>
                    <![CDATA[ Website analytics are crucial for understanding how visitors interact with your content. And while Google Analytics dominates the market, it often raises privacy concerns and can be complex for small projects. If you’re looking for a simpler, open-so... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-your-own-google-analytics-alternative-using-umami/</link>
                <guid isPermaLink="false">6913c897ebd9f0fb2ba61c3a</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ privacy ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Tue, 11 Nov 2025 23:36:55 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762904171356/3c714de7-3aa3-4c4f-946f-23cecb747a2a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Website analytics are crucial for understanding how visitors interact with your content. And while Google Analytics dominates the market, it often raises privacy concerns and can be complex for small projects.</p>
<p>If you’re looking for a simpler, open-source, and privacy-friendly solution, <a target="_blank" href="https://github.com/umami-software/umami">Umami</a> is a great alternative. It’s lightweight, easy to deploy, and doesn’t track personal data, making it compliant with modern privacy laws like GDPR.</p>
<p>In this article, you’ll learn what Umami is, why it’s an excellent Google Analytics alternative, and how to set it up on your own server from scratch using Sevalla.</p>
<h2 id="heading-what-well-cover">What We’ll Cover:</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-understanding-umami">Understanding Umami</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-choose-umami-over-google-analytics">Why Choose Umami Over Google Analytics</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-umami">How to Install Umami</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-get-the-source-code">Step 1: Get the Source Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-configure-the-database">Step 2: Configure the Database</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-build-the-application">Step 3: Build the Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-start-the-server">Step 4: Start the Server</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-keeping-umami-updated">Step 5: Keeping Umami Updated</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-6-adding-tracking-to-your-website">Step 6: Adding Tracking to Your Website</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-7-exploring-the-dashboard">Step 7: Exploring the Dashboard</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-hosting-umami-on-the-cloud-using-sevalla">Hosting Umami on the Cloud using Sevalla</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-privacy-and-compliance">Privacy and Compliance</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-understanding-umami">Understanding Umami</h2>
<p>Umami is an open-source web analytics platform designed to be fast, simple, and privacy-focused.</p>
<p>It collects essential website data like page views, referrals, and device information without storing personally identifiable details. Unlike Google Analytics, Umami doesn’t use cookies or share data with third parties.</p>
<p>The project is actively maintained by the open-source community and has grown into one of the most trusted tools for developers and businesses who want full control over their analytics. It provides a clean dashboard that shows all the key metrics in real time and works across any website or application.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762526959534/6eb011e3-c2e4-4c22-afbe-278aa7c89847.png" alt="Umami Dashboard" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can find the project on GitHub at github.com/umami-software/umami and even try a <a target="_blank" href="https://cloud.umami.is/analytics/eu/share/LGazGOecbDtaIwDr">live demo here</a>.</p>
<h2 id="heading-why-choose-umami-over-google-analytics">Why Choose Umami Over Google Analytics</h2>
<p>Google Analytics is powerful but often overwhelming for simple websites. It’s also tied to Google’s data collection ecosystem, which can conflict with privacy-focused organizations.</p>
<p>Umami takes a different approach. It collects only the information you need to make decisions, such as traffic sources and popular pages, and it stores everything on your own infrastructure.</p>
<p>There are no third-party cookies, no user tracking, and no hidden integrations. You get complete ownership of your data and peace of mind knowing that it’s not leaving your server.</p>
<p>Plus, Umami is free under the MIT license, making it suitable for both personal projects and commercial deployments.</p>
<h2 id="heading-how-to-install-umami">How to Install Umami</h2>
<p>Before you begin, make sure you have a few basic tools and requirements ready.</p>
<p>You’ll need a server with Node.js version 18.18 or newer installed. Umami also requires a database to store analytics data. It supports PostgreSQL (version 12.14 or higher), MySQL (version 8.0 or higher), and MariaDB (version 10.5 or higher).</p>
<h3 id="heading-step-1-get-the-source-code">Step 1: Get the Source Code</h3>
<p>The first step is to download the Umami source code from GitHub. Open your terminal and run:</p>
<pre><code class="lang-powershell">git clone https://github.com/umami<span class="hljs-literal">-software</span>/umami.git
</code></pre>
<pre><code class="lang-powershell"><span class="hljs-built_in">cd</span> umami
</code></pre>
<pre><code class="lang-powershell">pnpm install
</code></pre>
<p>The pnpm install command installs all the necessary dependencies for the application. Make sure you have pnpm installed globally before running this command. You can install it by running <code>npm install -g pnpm</code>.</p>
<h3 id="heading-step-2-configure-the-database">Step 2: Configure the Database</h3>
<p>Next, you need to configure a database connection. Create a new .env file in the root directory of the Umami project. Inside this file, add the following line:</p>
<pre><code class="lang-powershell">DATABASE_URL=connection<span class="hljs-literal">-url</span>
</code></pre>
<p>Replace <code>connection-url</code> with your actual database connection string. Here are two examples depending on your database type:</p>
<p>For PostgreSQL:</p>
<pre><code class="lang-powershell">postgresql://username:password@localhost:<span class="hljs-number">5432</span>/umami
</code></pre>
<p>For MySQL:</p>
<pre><code class="lang-powershell">mysql://username:password@localhost:<span class="hljs-number">3306</span>/umami
</code></pre>
<p>This connection string allows Umami to connect to your database and automatically create the necessary tables during the setup.</p>
<h3 id="heading-step-3-build-the-application">Step 3: Build the Application</h3>
<p>Once your configuration is complete, you can build the application by running:</p>
<pre><code class="lang-powershell">pnpm run build
</code></pre>
<p>This step compiles the code and prepares it for production. It will also initialize your database with the required tables and create a default admin account.</p>
<p>You can log in with the username <code>admin</code> and password <code>umami</code> after setup. It’s a good idea to change this password immediately once you log in for the first time.</p>
<h3 id="heading-step-4-start-the-server">Step 4: Start the Server</h3>
<p>Now it’s time to start the application. Run the following command:</p>
<pre><code class="lang-powershell">pnpm run <span class="hljs-built_in">start</span>
</code></pre>
<p>By default, Umami will start on <a target="_blank" href="http://localhost:3000.">http://localhost:3000.</a> You can open this address in your browser to access the analytics dashboard. If you want to make it accessible publicly, you’ll need to configure a reverse proxy using a web server like nginx.</p>
<h3 id="heading-step-5-keeping-umami-updated">Step 5: Keeping Umami Updated</h3>
<p>Like any software, Umami receives regular updates that include new features, security patches, and performance improvements. Keeping your installation up to date is simple.</p>
<p>If you installed from source, navigate to your Umami folder and run:</p>
<pre><code class="lang-powershell">git pull
</code></pre>
<pre><code class="lang-powershell">pnpm install
</code></pre>
<pre><code class="lang-powershell">pnpm run build
</code></pre>
<p>This command updates the source code, installs new dependencies, and rebuilds the app. If you are using Docker, you can update by pulling the latest images and restarting the containers:</p>
<pre><code class="lang-powershell">docker compose pull
</code></pre>
<pre><code class="lang-powershell">docker compose up — force<span class="hljs-literal">-recreate</span> <span class="hljs-literal">-d</span>
</code></pre>
<p>Regularly updating ensures you have access to the latest analytics features and bug fixes.</p>
<h3 id="heading-step-6-adding-tracking-to-your-website">Step 6: Adding Tracking to Your Website</h3>
<p>After you log in to the dashboard, you’ll see an option to add a new website. Once you create it, Umami will generate a small tracking script.</p>
<p>Copy the script tag and paste it into the &lt;head&gt; section of your website’s HTML pages.</p>
<p>This script is lightweight and won’t slow down your website. Once added, you’ll start seeing traffic data in your dashboard almost instantly.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762526987669/f1bb73cd-2e04-43e5-95a9-105f16e80f0c.png" alt="Umami Traffic sources" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can track multiple websites from the same Umami installation, making it ideal for developers managing several projects.</p>
<h3 id="heading-step-7-exploring-the-dashboard">Step 7: Exploring the Dashboard</h3>
<p>The Umami dashboard is clean, modern, and easy to understand. It shows metrics such as page views, referrers, operating systems, and devices. You can filter by date, view live visitors, and export data for reporting.</p>
<p>There are no complicated configuration options or hidden features  –  just the information you need to make informed decisions about your website traffic. Everything runs fast, even on modest servers.</p>
<h2 id="heading-hosting-umami-on-the-cloud-using-sevalla">Hosting Umami on the Cloud using Sevalla</h2>
<p>When you are ready to move beyond testing, Umami gives you two options. You can self-host it using your own infrastructure or use their managed cloud version at <a target="_blank" href="https://umami.is/">Umami.is</a>.</p>
<p>Self-hosting gives you full control and is usually preferred by technical teams who want to keep sensitive data in-house.</p>
<p>You can choose any cloud provider, like AWS, DigitalOcean, or others to set up Umami. But I will be using Sevalla.</p>
<p><a target="_blank" href="https://sevalla.com/">Sevalla</a> is a PaaS provider designed for developers and dev teams shipping features and updates constantly in the most efficient way. It offers application hosting, database, object storage, and static site hosting for your projects.</p>
<p>I am using Sevalla for two reasons:</p>
<ul>
<li><p>Every platform will charge you for creating a cloud resource. Sevalla comes with a $50 credit for us to use, so we won’t incur any costs for this example.</p>
</li>
<li><p>Sevalla has a <a target="_blank" href="https://docs.sevalla.com/templates/overview">template for Umami</a>, so it simplifies the manual installation and setup for each resource you will need for installation.</p>
</li>
</ul>
<p><a target="_blank" href="https://app.sevalla.com/login">Log in</a> to Sevalla and click on Templates. You can see Umami as one of the templates.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762527152703/5fdd384a-bbc0-474a-a977-501ffbcaa906.png" alt="Sevalla Templates" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Click on the “Umami” template. You will see the resources needed to provision the application like PostgreSQL and Redis. Click on “Deploy Template”</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762527179056/93d52be1-813f-41fa-9790-120639602275.png" alt="Sevalla Deployments" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can see the resource being provisioned. Once the resources are provisioned, go to your Umami application and click on “Visit app”</p>
<p>You will get a cloud URL with a login page. Use the default login credentials admin for username and umami for password. You will see the empty dashboard.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762527213359/63015ae9-8716-4819-80c5-4352a163b87f.png" alt="Umami Dashboard" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You now have a production-grade Umami server running on the cloud. You can use this to setup analytics for your website by clicking on “Settings” and then “Add website”.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762527254085/e6b53462-8361-47f1-afe0-dc4c23a1734e.png" alt="Umami Website Setup" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can then click “Edit” to get the tracking code for your website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762527330314/e03b25a5-9558-4937-a6dc-5d0fb50a83e3.png" alt="Umami Website Configuration" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Once you add the tracking code for your website, you can start monitoring your traffic and other analytics in your new dashboard.</p>
<h2 id="heading-privacy-and-compliance">Privacy and Compliance</h2>
<p>One of the best reasons to use Umami is its commitment to privacy. It doesn’t use cookies, doesn’t track individual users, and doesn’t share data with any third-party service.</p>
<p>All information stays on your server. This makes it a great choice for websites that need to comply with privacy laws like GDPR, CCPA, or PECR.</p>
<p>Since you own the data, you can decide how long to keep it, how to analyze it, and who has access.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Setting up your own analytics system might sound complex, but with Umami, it’s surprisingly easy. It gives you everything you need to understand your website traffic without compromising user privacy. You control the data, the infrastructure, and the configuration.</p>
<p>By following these steps, you can deploy Umami on your own server in less than an hour and start monitoring your website visitors right away. Whether you run a personal blog, a SaaS platform, or a client project, Umami offers a transparent, fast, and privacy-friendly alternative to Google Analytics.</p>
<p><em>Hope you enjoyed this article. Find me on</em> <a target="_blank" href="https://linkedin.com/in/manishmshiva"><em>Linkedin</em></a> <em>or</em> <a target="_blank" href="https://manishshivanandhan.com/"><strong><em>visit my website</em></strong></a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build an Analytical Dashboard with Next.js ]]>
                </title>
                <description>
                    <![CDATA[ If you work with data or plan to in the future, at some point you'll likely need to build a comprehensive analytics dashboard. Sharing data through charts is a great way to provide others with a clearer understanding of this information. Pairing it w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-an-analytical-dashboard-with-nextjs/</link>
                <guid isPermaLink="false">67a3aa3efc0a24bff2e83e65</guid>
                
                    <category>
                        <![CDATA[ flexmonster ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ dashboard ]]>
                    </category>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ highcharts ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Stefan Muzyka ]]>
                </dc:creator>
                <pubDate>Wed, 05 Feb 2025 18:13:18 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738347998117/46877c78-f5e5-4a94-954e-029b73b8f952.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you work with data or plan to in the future, at some point you'll likely need to build a comprehensive analytics dashboard.</p>
<p>Sharing data through charts is a great way to provide others with a clearer understanding of this information. Pairing it with a pivot table is also a smart approach, allowing you to view your data from different perspectives. And what if you could also aggregate data and customize charts to suit your needs?</p>
<p>In this guide, I’ve consolidated my knowledge on creating an analytics dashboard in Next.js using Flexmonster and Highcharts. To make it engaging, we’ll explore some interesting survey results about passenger flying etiquette. I hope you find it helpful. Let’s roll!</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-subject-area">The Subject Area</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-final-dashboard">The Final Dashboard</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-highcharts-and-flexmonster-for-our-next-js-app">How to Configure Highcharts and Flexmonster for Our Next.js App</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-the-dashboard">How to Set Up the Dashboard</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-the-chart-configuration">How to Set Up the Chart Configuration</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-filling-up-the-dashboard-with-other-charts">Filling Up the Dashboard with Other Charts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-connect-between-flexmonster-and-highcharts">Connect between Flexmonster and Highcharts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-full-demo-link">Full demo link</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-wrapping-up">Wrapping up</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ol>
<li><p>Install Next.js (installation guide <a target="_blank" href="https://nextjs.org/docs/app/getting-started/installation">here</a>)</p>
</li>
<li><p>In this project we’ll use the <code>flexmonster</code>, <code>react-flexmonster</code>, and <code>highcharts</code> libraries.</p>
</li>
</ol>
<pre><code class="lang-bash">npm i react flexmonster react-flexmonster highcharts highcharts-react-official
npm i -g flexmonster-cli
</code></pre>
<p>These are paid tools for sharing analytics but offer more options for working with data and customization. You can also use free/open-source alternatives like:</p>
<p><strong>Data/Analytics Libraries:</strong></p>
<ul>
<li><p><a target="_blank" href="https://github.com/nicolaskruchten/pivottable">PivotTable.js</a> — basic open-source pivot functionality</p>
</li>
<li><p><a target="_blank" href="https://www.npmjs.com/package/orb">Orb</a> — clean pivot UI with neat design</p>
</li>
<li><p><a target="_blank" href="https://www.webdatarocks.com/demos/react/pivot-table-demo/">WebDataRocks</a> — modern, free pivot table solution</p>
</li>
</ul>
<p><strong>Charts:</strong></p>
<ol>
<li><p><a target="_blank" href="https://nivo.rocks/">Nivo</a> — awesome free charts with D3 power</p>
</li>
<li><p><a target="_blank" href="https://www.chartjs.org/">Chart.js</a> — simple yet powerful canvas charts</p>
</li>
<li><p><a target="_blank" href="https://recharts.org/en-US/">Recharts</a> — React components for D3 charts</p>
</li>
</ol>
<h2 id="heading-the-subject-area"><strong>The Subject Area</strong></h2>
<p>Have you ever been curious about why people get so angry on planes with others' behavior? Or maybe you’re that person who’s… misbehaving? Have you wondered if it’s okay to bother your neighbors onboard, whether it’s for stepping out of your seat or asking for something?</p>
<p>Imagine: you board a plane with your friends, and you are seated apart, not all together. You want to change places with someone to sit near each other. How likely is it that the person next to you will consider this to be rude or unacceptable?</p>
<p>We can explore these questions through a <a target="_blank" href="https://fivethirtyeight.com/features/airplane-etiquette-recline-seat/">survey</a> on passenger etiquette conducted by ABC News. Our goal is to examine passengers' attitudes toward in-flight interactions and present our findings with charts and a pivot table. The complete survey data is sourced from <a target="_blank" href="https://github.com/fivethirtyeight/data/tree/master/flying-etiquette-survey">here</a>.</p>
<p>In this guide, I’ll highlight some intriguing correlations between different social groups and their perspectives on certain questions, such as:</p>
<ul>
<li><p>The impact of age and income on overall dissatisfaction.</p>
</li>
<li><p>What behaviors do passengers consider the rudest?</p>
</li>
<li><p>How does traveling with children affect the flight experience?</p>
</li>
<li><p>Which social groups tend to leave the flight most satisfied or dissatisfied?</p>
</li>
<li><p>Who is more likely to break flight rules?</p>
</li>
</ul>
<h2 id="heading-the-final-dashboard"><strong>The Final Dashboard</strong></h2>
<p>In this tutorial, we’ll create an interactive dashboard using Next.js, featuring a pivot table and several charts on the final page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736375903721/ea1faca7-0bf3-4d32-83fc-5963035b832e.png" alt="The final dashboard" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-tools"><strong>Tools</strong></h3>
<p>I was looking for the tools that offer customizable and functional UI, wide range of chart types and pivot table features. So, I focused on <a target="_blank" href="https://www.flexmonster.com/">Flexmonster</a> for creating tables and <a target="_blank" href="https://www.highcharts.com/">Highcharts</a> for the charts. These tools offer user-friendly interfaces, extensive customization options, handle large datasets, and integrate with each other.</p>
<p>Now, let's delve into the process of integration.</p>
<h2 id="heading-how-to-configure-highcharts-and-flexmonster-for-our-nextjs-app"><strong>How to Configure Highcharts and Flexmonster for Our Next.js App</strong></h2>
<p>In order to create the analytical dashboard, you’ll need to install the libraries and configure your project. </p>
<h3 id="heading-1-define-the-nextjs-project">1. Define the Next.js project:</h3>
<pre><code class="lang-bash">npx create-next-app flexmonster-project --ts --app
<span class="hljs-built_in">cd</span> flexmonster-project
</code></pre>
<h3 id="heading-2-get-the-flexmonster-wrapper-for-react">2. Get the Flexmonster wrapper for React:</h3>
<pre><code class="lang-bash">flexmonster add react-flexmonster
</code></pre>
<p>Got it, libraries are now actually installed! Now, let’s move further, embedding them into the project.</p>
<h3 id="heading-3-import-flexmonster-styles-to-globalcss">3. Import Flexmonster styles to <code>global.css</code>:</h3>
<pre><code class="lang-bash">@import <span class="hljs-string">"flexmonster/flexmonster.css"</span>;
</code></pre>
<h3 id="heading-4-create-the-wrapper">4. Create the wrapper</h3>
<p>Now you’ll create the wrapper for your future pivot table that integrates Flexmonster and Highcharts. First, let’s create a <code>PivotWrapper.tsx</code> file.</p>
<pre><code class="lang-typescript"><span class="hljs-string">'use client'</span>
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> FlexmonsterReact <span class="hljs-keyword">from</span> <span class="hljs-string">"react-flexmonster"</span>;
<span class="hljs-keyword">import</span> Flexmonster <span class="hljs-keyword">from</span> <span class="hljs-string">'flexmonster'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"flexmonster/lib/flexmonster.highcharts.js"</span>;


<span class="hljs-comment">// take general Flexmonster parameters and some special for Next.js</span>
<span class="hljs-keyword">type</span> PivotProps = Flexmonster.Params &amp; {
    pivotRef?: React.ForwardedRef&lt;FlexmonsterReact.Pivot&gt;;
  }

<span class="hljs-comment">// pivotRef provides a reference to the Flexmonster instance for accessing the Flexmonster API.</span>
<span class="hljs-keyword">const</span> PivotWrapper: React.FC&lt;PivotProps&gt; = <span class="hljs-function">(<span class="hljs-params">{ pivotRef, ...params}</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> (
        &lt;FlexmonsterReact.Pivot
            {...params}
            ref={pivotRef}
        /&gt;
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> PivotWrapper;
</code></pre>
<h3 id="heading-5-import-the-wrapper">5. Import the wrapper</h3>
<p>Now, import the wrapper in the <code>analytical-dashboard/page.tsx</code> file. You can change the route name <code>analytical-dashboard</code> to your liking:</p>
<pre><code class="lang-typescript"><span class="hljs-string">"use client"</span>
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-keyword">type</span> { Pivot } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-flexmonster"</span>;
<span class="hljs-keyword">import</span> dynamic <span class="hljs-keyword">from</span> <span class="hljs-string">"next/dynamic"</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> Highcharts <span class="hljs-keyword">from</span> <span class="hljs-string">'highcharts'</span>;
<span class="hljs-keyword">import</span> HighchartsReact <span class="hljs-keyword">from</span> <span class="hljs-string">'highcharts-react-official'</span>;


<span class="hljs-comment">// Load the wrapper dynamically</span>
<span class="hljs-keyword">const</span> PivotWrap = dynamic(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'@/app/PivotWrapper'</span>), {
    ssr: <span class="hljs-literal">false</span>,
    loading: <span class="hljs-function">() =&gt;</span> &lt;h1&gt;Loading Flexmonster...&lt;/h1&gt;
});


<span class="hljs-keyword">const</span> ForwardRefPivot = React.forwardRef&lt;Pivot, Flexmonster.Params&gt;(<span class="hljs-function">(<span class="hljs-params">props, ref?: React.ForwardedRef&lt;Pivot&gt;</span>) =&gt;</span>
    &lt;PivotWrap {...props} pivotRef={ref} /&gt;

)

ForwardRefPivot.displayName = <span class="hljs-string">'ForwardRefPivot'</span>;
</code></pre>
<p>By the way, Flexmonster supports dynamic loading for its tables, which provides a smooth experience when extracting large amounts of data. </p>
<h3 id="heading-6-place-your-pivot-wrapper-and-charts-into-the-dashboard">6. Place your pivot wrapper and charts into the dashboard.</h3>
<p>Let’s define a <code>WithHighcharts()</code> function to render our dashboard and work with its essential parts. First, we’ll initialize the <a target="_blank" href="https://react.dev/reference/react/useRef">ref object</a> for the pivot table to access it and its events. The charts will be created in the <code>createChart()</code> function, which runs when pivot data loads (in the <code>reportComplete</code> event). Finally, we return the <code>layout</code> function.</p>
<p>Add the code below to the <code>analytical-dashboard/page.tsx</code> file:</p>
<pre><code class="lang-typescript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">WithHighcharts</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> pivotRef: React.RefObject&lt;Pivot&gt; = React.useRef&lt;Pivot&gt;(<span class="hljs-literal">null</span>);

    <span class="hljs-keyword">const</span> reportComplete = <span class="hljs-function">() =&gt;</span> {
        pivotRef.current!.flexmonster.off(<span class="hljs-string">"reportComplete"</span>, reportComplete);
        createChart();
    }

    <span class="hljs-comment">// define and create charts on the page. Called when data loading is successfully completed</span>
    <span class="hljs-keyword">const</span> createChart = <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// here we will place charts rendering later</span>
    }

    <span class="hljs-keyword">return</span> (
        &lt;div className=<span class="hljs-string">"App"</span>&gt;
            &lt;div id=<span class="hljs-string">"pivot-container"</span> className=<span class="hljs-string">""</span>&gt;
              &lt;ForwardRefPivot
                ref={pivotRef}
                toolbar={<span class="hljs-literal">true</span>}
                beforetoolbarcreated={<span class="hljs-function"><span class="hljs-params">toolbar</span> =&gt;</span> {
                  toolbar.showShareReportTab = <span class="hljs-literal">true</span>;
                }}
                shareReportConnection={{
                  url: <span class="hljs-string">"https://olap.flexmonster.com:9500"</span>
                }}
                width=<span class="hljs-string">"100%"</span>
                height={<span class="hljs-number">600</span>}
                report = {{
                  dataSource: {
                    <span class="hljs-keyword">type</span>: <span class="hljs-string">"csv"</span>,
                    <span class="hljs-comment">// connect to our dataset</span>
                    filename: <span class="hljs-string">"https://query.data.world/s/vvjzn4x5anbdunavdn6lpu6tp2sq3m?dws=00000"</span>
                  }
                }}
                reportcomplete={reportComplete}
                <span class="hljs-comment">// your license key</span>
                licenseKey=<span class="hljs-string">"XXXX-XXXX-XXXX-XXXX-XXXX"</span>
              /&gt;
          &lt;/div&gt;

          <span class="hljs-comment">// here we will place chart layouts</span>
    )
}
</code></pre>
<h3 id="heading-7-run-the-application">7. Run the application:</h3>
<pre><code class="lang-bash">npm run build
npm start
</code></pre>
<p>If you are interested in a detailed integration of Flexmonster with <a target="_blank" href="https://www.flexmonster.com/doc/integration-with-next-js/">Next.js</a> and <a target="_blank" href="https://www.flexmonster.com/doc/integration-with-highcharts/">Highcharts</a>, you can check the complete documentation that I’ve linked here.</p>
<p>For now, we’ve set up a blank dashboard that’s ready to be populated with data. In the next section, I’ll walk you through the overall chart definition process and highlight some key considerations.</p>
<p>First, you’ll need to ensure that your charts update based on the filters applied to the grid. For that, you need to add the following snippet of code:</p>
<pre><code class="lang-typescript"> React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (pivotRef.current) {
        <span class="hljs-keyword">const</span> pivot = pivotRef.current.flexmonster;

        <span class="hljs-comment">// Trigger the chart update when data changes</span>
        pivot.on(<span class="hljs-string">'dataChanged'</span>, createChart);
        pivot.on(<span class="hljs-string">'filterclose'</span>, createChart);


        <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
          pivot.off(<span class="hljs-string">'dataChanged'</span>, createChart);
          pivot.off(<span class="hljs-string">'filterclose'</span>, createChart);
        }
    }
}, [pivotRef]);
</code></pre>
<p>In this case, Next.js tracks the <a target="_blank" href="https://www.flexmonster.com/api/filterclose/?r=stfc2"><code>filterClose</code></a> event and triggers the <code>createChart()</code> function, which updates the charts. Unfortunately, there is no event for filter changes, only for filter pop-up window opening/closing. So, I used the event that triggers on filter pop-up window closing, as I usually use it for applying filters. You can read more about Flexmonster events <a target="_blank" href="https://www.flexmonster.com/api/events/?r=stfc2">here</a>.</p>
<h2 id="heading-how-to-set-up-the-dashboard"><strong>How to Set Up the Dashboard</strong></h2>
<p>To get started, let's get acquainted with our pivot table. The upcoming charts will draw information directly from it, so it's a good idea to first understand how the dashboard works.</p>
<p>In the previous step, we already created a default grid. If you run it now, it will look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736375968187/a71c06db-1f6d-4d0a-ad0e-4b4457d5f575.png" alt="The default grid of the Flexmonster pivot table" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>It simply displays some default data from the dataset. Not bad, but we want to configure more representative data and explore the full potential of Flexmonster.</p>
<h3 id="heading-1-configure-the-pivot-table"><strong>1. Configure the pivot table</strong></h3>
<p>The main buttons that allow you to configure what and how the data is displayed in the table are <strong>Format</strong>, <strong>Settings</strong>, and <strong>Fields</strong>. We’ll start with Fields.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376015936/122a95ed-98aa-4128-9c18-d31e95be4437.gif" alt="GIF: connecting dataset fields to the grid" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>By opening the Fields tab, you can select which columns from your dataset you want to display in the table. What shall we choose?</p>
<p>Hmm… It seems interesting to see the percentage distribution of respondents of different ages across various regions. Some polled regions likely have more older respondents, some younger, and others may have a balanced mix. This is more about analyzing the composition of the survey itself, but it’s a good start.</p>
<p>To achieve this, select the necessary fields in Rows and Columns. Next, choose the function to calculate the final values. There are quite a few options, but we’ll go with <strong>Percentage of column</strong>. As a result, you’ll get the percentage distribution of respondents of specific age groups in each region.</p>
<p>Here we go:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376040585/181e9f1d-38ed-4731-8700-bbee02a7bbd5.png" alt="Location and Age grid with raw data" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Alright, let’s tidy up this table a bit. We’ll keep just one decimal place, which you can do in the <strong>Format</strong> tab like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736378089026/8e853863-86ee-40a8-be66-6fa9c339f164.png" alt="Format tab" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>It’s quite simple: select the required field (in this case, there will only be one) in the <strong>Choose Value</strong> field and set <strong>Decimal Places</strong> to 1.</p>
<p>We’ll also remove the <strong>Grand Totals</strong> since they are unnecessary for our purposes. You can do this in the <strong>Settings</strong> tab:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736378067956/a66dd0f9-0589-473e-b0af-c9c6bfe0d0b1.png" alt="Layout options" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Finally, we’ll want to remove blank responses. This is a feature of the selected dataset – some respondents chose not to answer certain questions, leaving the response field blank. For our analysis, this data is unnecessary, so we’ll filter it out.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376126270/4bc3f72c-5e68-4e39-b1da-19f179ad2e4f.gif" alt="GIF: filtering data" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>And here’s how the table looks now. Quite neat!</p>
<h3 id="heading-2-conditional-formatting"><strong>2. Conditional Formatting</strong></h3>
<p>Now we want to set up conditional formatting to highlight standout data. The table is already configured, but adding visual cues will make the information easier to interpret. Fortunately, Flexmonster supports this feature, so let’s use it.</p>
<p>Here’s my idea: we want to identify areas where the distribution of respondents by age is uneven. We have four age ranges: youngsters (18-29), millennials (30-44), Gen X (45-59), and seniors (60+). In a balanced distribution, each age group should account for 100/4 = 25% (with a margin of ±2÷3%).</p>
<p>Here’s the plan:</p>
<ul>
<li><p>22-27%: Average distribution (within range).</p>
</li>
<li><p>17-22% or 27-32%: slightly underrepresented or overrepresented.</p>
</li>
<li><p>&lt;17% or &gt;32%: strongly underrepresented or overrepresented.</p>
</li>
</ul>
<p>In the <strong>Format</strong> tab, select <strong>Conditional Formatting</strong> and add conditions. Define the range with the value it applies to, and the highlight color. As a result, you’ll get a table that looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376163028/c7c28901-30b4-49f7-b146-2ed5e6dbfc9f.gif" alt="GIF: Conditional formatting" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>According to the table, most respondents are middle-aged. In some cases, they make up the majority of polled people of their region. The most unbalanced distribution is around the East South Central and Middle-Atlantic states. There are overrepresented in one age group, and underrepresented in others. </p>
<p>Awesome! We’ve explored the Flexmonster table. Beyond displaying data, it can also filter data for all our upcoming charts. Let’s move on to setting up the charts, and I’ll show you how the table can influence its data.</p>
<h2 id="heading-how-to-set-up-the-chart-configuration"><strong>How to Set Up the Chart Configuration</strong></h2>
<p>In this section, we’ll create pie, bar, column, area, and line charts. It sounds like a lot, but Highcharts provides a wide range of <a target="_blank" href="https://www.highcharts.com/docs/chart-and-series-types/chart-types">chart types</a>. You can also customize them to your liking.</p>
<p>First, we’ll create a <a target="_blank" href="https://www.highcharts.com/docs/chart-and-series-types/pie-chart">pie chart</a> showing location distribution of passengers. While a basic pie chart would typically be a circle, I’m opting for a donut chart instead. This example demonstrates the common chart configuration process. For other charts, simply modify the chart type, rows, and measures. You can also play with dataset fields and chart types to your liking.</p>
<h3 id="heading-1-insert-highcharts-into-the-page"><strong>1. Insert Highcharts into the page.</strong></h3>
<p>First, move down to the <code>return()</code> section. at the bottom, leave a free place for the chart layouts. So, here we’ll insert the first <code>&lt;div&gt;</code> block to store the future pie chart. As it’s about the etiquette of passengers onboard, let’s assign it an id of <code>chart-location-distribution</code>: </p>
<pre><code class="lang-typescript">&lt;div className=<span class="hljs-string">"chart-item"</span>&gt;
  &lt;h2&gt;Location Distribution&lt;/h2&gt;
  &lt;div id=<span class="hljs-string">"chart-location-distribution"</span>&gt;&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<h3 id="heading-2-define-the-chart-options"><strong>2. Define the chart options.</strong></h3>
<p>Let’s move on to the <code>createChart()</code> function. At the moment, it’s empty. To define the chart, paste <a target="_blank" href="https://www.flexmonster.com/doc/integration-with-highcharts/?r=stfc2"><code>pivotRef.current!.flexmonster.highcharts?.getData()</code></a> into it. It gets three parameters inside: <code>chart options</code>, <code>callbackHandler</code>, and <code>updateHandler</code>.</p>
<pre><code class="lang-typescript">pivotRef.current!.flexmonster.highcharts?.getData(
    <span class="hljs-comment">// getting the current slice of data from the grid to apply filters to the chart</span>
    <span class="hljs-keyword">const</span> gridSlice = pivotRef.current!.flexmonster.getReport()?.slice <span class="hljs-keyword">as</span> Flexmonster.Slice
        {
            <span class="hljs-keyword">type</span>: <span class="hljs-string">'pie'</span>,
            slice: {
                rows: [{ uniqueName: <span class="hljs-string">'Location (Census Region)'</span>, }],
                measures: [
                    {
                        uniqueName: <span class="hljs-string">'RespondentID'</span>,
                        aggregation: <span class="hljs-string">'count'</span>,
                    },
                ],
                <span class="hljs-comment">// apply current grid filters to the chart</span>
                reportFilters: gridSlice.reportFilters
            },
        },
    <span class="hljs-comment">// ...</span>
    <span class="hljs-comment">// in the next code section, I describe last two parameters</span>
    <span class="hljs-comment">// to be continued</span>
)
</code></pre>
<p>Since we pass chart options as Flexmonster.Slice from <code>getReport()</code>, the data updates dynamically from the grid. The <code>Slice</code> object specifies which data sample to display on the chart by selecting from the dataset. You can read more about the properties of grid slices <a target="_blank" href="https://www.flexmonster.com/api/slice-object/">here</a>.</p>
<p>You can customize the chart by changing data properties inside the <code>callbackHandler</code> parameter. Down below, we’ll create a custom donut chart by doing this:</p>
<pre><code class="lang-typescript">pivotRef.current!.flexmonster.highcharts?.getData(
  <span class="hljs-comment">// ...</span>
  <span class="hljs-comment">// continuing of configuring chart</span>
  <span class="hljs-comment">// chart options parameter defined in previous code section</span>

  (data: <span class="hljs-built_in">any</span>) =&gt; {  
        <span class="hljs-comment">// Define the chart configuration within the data object</span>
        data.chart = {
            <span class="hljs-keyword">type</span>: <span class="hljs-string">'pie'</span>,
        };

        data.title = {
            text: <span class="hljs-string">'Aggregated Survey Responses'</span>
        };

        data.legend = {
            layout: <span class="hljs-string">'horizontal'</span>,
            align: <span class="hljs-string">'center'</span>,
            verticalAlign: <span class="hljs-string">'bottom'</span>, 
            x: <span class="hljs-number">0</span>,
            y: <span class="hljs-number">10</span>, 
        }

        data.plotOptions = {
            pie: {
                innerSize: <span class="hljs-string">'50%'</span>,
                dataLabels: {
                    enabled: <span class="hljs-literal">true</span>,
                    format: <span class="hljs-string">'&lt;b&gt;{point.name}&lt;/b&gt;: {point.percentage:.1f} %'</span>,
                },
            },
        };

        Highcharts.chart(<span class="hljs-string">'chart-location-distribution'</span>, data);
    },
    <span class="hljs-function">(<span class="hljs-params">data: <span class="hljs-built_in">any</span></span>) =&gt;</span> {
        Highcharts.chart(<span class="hljs-string">'chart-location-distribution'</span>, data);
    }
)
</code></pre>
<p><strong>Note!</strong> You should change <code>data</code> <strong>before</strong> it passes to the <code>Highcharts.chart()</code> function as a parameter.</p>
<h3 id="heading-3-completed-location-distribution-pie-chart"><strong>3. Completed Location Distribution Pie Chart</strong></h3>
<p>The chart shows that the most common passengers on this airline are locals from the Pacific, and the least common passengers are from the East South Central states. This is quite interesting. It might be because the Pacific region includes large cities such as San Francisco, Los Angeles, Seattle, and Portland, while the East South Central region includes states like Mississippi and Alabama, which have smaller populations and population density.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376204736/797d7944-cc61-454f-9cbc-f3d9d2d24e43.png" alt="'Location distribution' pie chart" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-filling-up-the-dashboard-with-other-charts"><strong>Filling Up the Dashboard with Other Charts</strong></h2>
<p>Now, let’s create the remaining charts following the same process – adjusting the chart <code>type</code>, <code>slice</code> options, and <code>callbackHandler</code> functions for each diagram. You can find the full chart configuration of each chart at <a class="post-section-overview" href="#heading-full-demo-link">the end of the guide</a> on my GitHub.</p>
<h3 id="heading-1-frequency-of-using-airlines-distributed-by-locations"><strong>1. Frequency of using airlines distributed by locations</strong></h3>
<p>Here we can see with a <a target="_blank" href="https://www.highcharts.com/docs/chart-and-series-types/column-chart">stacked column chart</a> how often people from different regions fly.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376209953/a1fd26e5-c7eb-4612-a376-dcb61315d61a.png" alt="'Frequency of using airlines distributed by locations' stacked column chart" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The average passenger from regions across the board tend to fly infrequently, with most flying once a year. Overall, the trend suggests that flying habits are influenced by regional factors, with occasional travel being more common than frequent flying. An interesting fact is that many of the polled people here have never flown! (How did they get into this poll?!)</p>
<h3 id="heading-2-who-breaks-the-rules-on-board"><strong>2. Who breaks the rules on board?</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376226439/2c8c093e-e4b3-4964-9097-5110b6813f6f.png" alt="'Frequency of travel to rule violations' bar chart" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Tricky question, isn’t it? We all know that smoking and using electronics are prohibited on board. But not everyone follows these rules, and fewer will admit to breaking them.</p>
<p>Still, pollsters managed to gather some insights about rule violations. The <a target="_blank" href="https://www.highcharts.com/docs/chart-and-series-types/bar-chart">bar chart</a> above reveals a trend: frequent flyers tend to neglect the rules, while those who fly less often are more likely to follow them.</p>
<p>From my own experience, your first flights are stressful, and you typically try not to disrupt the delicate balance of the plane. Every rule feels crucial, almost sacred. But regular fliers don’t seem to think this way.</p>
<h3 id="heading-3-ease-of-communication-depending-on-age"><strong>3. Ease of communication depending on age</strong></h3>
<p>The <a target="_blank" href="https://www.highcharts.com/docs/chart-and-series-types/line-chart">line chart</a> below shows that age influences your ease of communication with strangers, with middle-aged people often feeling more comfortable initiating conversations.</p>
<p>Personally, I always enjoy befriending or communicating with strangers, as it brings a sense of connection. But for many people, especially on board a flight, approaching strangers can be difficult, with older passengers often feeling more hesitant to engage.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376241508/ebe08ce7-bcb9-4e08-8296-2ad4c953c4ac.png" alt="'Age and ease of communication' line chart" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>People aged 30-44 are most comfortable communicating with strangers during flights. In contrast, both younger passengers (under 30) and older passengers (60+) view excessive communication as rude and prefer to keep to themselves during the journey.</p>
<h3 id="heading-4-do-men-consider-bringing-children-onboard-ruder-than-women"><strong>4. Do men consider bringing children onboard ruder than women?</strong></h3>
<p>I thought that men might be more affected by unruly children in different spaces, so I decided to check that. The question asked was, ‘Is it rude to bring unruly children on board?’ The options were ‘No, not at all,’ ‘Yes, somewhat rude,’ and ‘Yes, it’s rude.’ So, I built another pie chart to see the relationship.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376256453/7d8b1e74-6c1a-45b1-8601-84dc4d806382.png" alt="Gender distribution of 'Yes, very rude' responses to question: 'Is it rude to bring unruly babies oboard?' pie chart" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Almost two-thirds of men chose the ‘Yes, rude’ option, while fewer women selected that answer.</p>
<h3 id="heading-5-peoples-demands-of-others-and-themselves"><strong>5. People's demands of others and themselves.</strong></h3>
<p>People often hold double standards, considering certain behaviors rude when done by others but not when they engage in those behaviors themselves. One of the most painful issues onboard is the mess created by reclining seats, which can affect the comfort of other passengers. This led me to research how people feel about reclining seats and how frequently they engage in the practice.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376314682/b686dc8d-ee38-4e98-b5db-6e8397d9f5c5.png" alt="'Seat recline and seat obligation' stacked column chart" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>An interesting correlation emerged in two key points: the most outraged passengers are often those who do not recline their seats and are usually the ones who can't tolerate when others do so. Also, there is always a small group of people who recline their seats regularly but are willing to argue with others about the same action.</p>
<h3 id="heading-6-which-age-group-tends-to-be-outraged"><strong>6. Which age group tends to be outraged?</strong></h3>
<p>The <a target="_blank" href="https://www.highcharts.com/docs/chart-and-series-types/area-chart">area chart</a> covers all the questions about what passengers consider rude, allowing us to observe how different age groups respond to various situations. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736376320810/9a9a31b8-565a-4044-b221-7d40f8fdf32e.gif" alt="'Age and 'Yes, it is rude' responds' area chart" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Interestingly, the most outraged responses are regarding babies onboard and people waking up to walk around the plane. Youngsters are most outraged by reclining seats, while passengers aged 30-44 tend to be more upset about people walking to the bathroom. Older passengers are also concerned about reclining seats.</p>
<p>The least outraged responses are about communicating with others and moving to unsold seats, indicating that gadgets haven’t completely stolen the value of live communication.</p>
<p>I attached links to the Highcharts documentation for each chart, but additional charts are available. You can inspect them <a target="_blank" href="https://www.highcharts.com/docs/chart-and-series-types/chart-typeshttps://www.highcharts.com/docs/chart-and-series-types/chart-types">here</a>.</p>
<h2 id="heading-how-to-sync-data-between-flexmonster-and-highcharts">How to Sync Data Between Flexmonster and Highcharts</h2>
<p>Let’s recall the earlier section on <a class="post-section-overview" href="#heading-2-define-the-chart-options">configuring chart options</a>. Here, adding the <code>reportFilters</code> field to the slice object enables data synchronization across all dashboard elements, from pivot table to charts.</p>
<p>To filter dashboard data, add fields to <strong>Report Filters</strong> in the <strong>Fields</strong> tab and observe chart updates. For example, filtering Location values affects the pie chart and column chart since they use Location data.</p>
<p>You can try it out by adding other rows to Report Filters and directly influence the appearance of your charts.</p>
<h2 id="heading-full-demo-link"><strong>Full Demo Link</strong></h2>
<p><img src="https://noname-hub.com/imgs/final.gif" alt="final" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can check out the full Next.js demo app and the dashboard yourself <a target="_blank" href="https://github.com/StefanErrorerko/AnalyticalDashboardFlyingEtiquette">here</a>.</p>
<h2 id="heading-wrapping-up"><strong>Wrapping up</strong></h2>
<p>In this tutorial, we built an interactive statistical dashboard, analyzed the subject matter, and processed the dataset. Along the way, we explored key configuration specifics for the libraries we used: Highcharts and Flexmonster. We then populated the dashboard with charts and demonstrated how to interact with it effectively.</p>
<p>I aimed to highlight a diverse and engaging dataset to make the process more interesting. I hope this guide serves as a helpful resource for building analytical dashboards in Next.js. Best of luck with your projects!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use GPT to Analyze Large Datasets ]]>
                </title>
                <description>
                    <![CDATA[ Absorbing and then summarizing very large quantities of content in just a few seconds truly is a big deal. As an example, a while back I received a link to the recording of an important 90 minute business video conference that I'd missed a few hours ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-gpt-to-analyze-large-datasets/</link>
                <guid isPermaLink="false">66cf65275dfeea789e899e2b</guid>
                
                    <category>
                        <![CDATA[ #ai-tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ generative ai ]]>
                    </category>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 28 Aug 2024 17:57:59 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724798393633/8ad22b7c-646c-4c02-894d-6a6b08447049.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Absorbing and then summarizing very large quantities of content in just a few seconds truly is a big deal. As an example, a while back I received a link to the recording of an important 90 minute business video conference that I'd missed a few hours before.</p>
<p>The reason I'd missed the live version was because I had no time (I was, if you must know, rushing to finish my <a target="_blank" href="https://amzn.to/3yLFT3b">Manning book, The Complete Obsolete Guide to Generative AI</a> – from which this article is excerpted).</p>
<p>Well, a half a dozen hours later I still had no time for the video. And, inexplicably, the book was still not finished.</p>
<p>So here's how I resolved the conflict the GPT way:</p>
<ul>
<li><p>I used OpenAI Whisper to generate a transcript based on the audio from the recording</p>
</li>
<li><p>I exported the transcript to a PDF file</p>
</li>
<li><p>I uploaded the PDF to ChatPDF</p>
</li>
<li><p>I prompted ChatPDF for summaries connected to the specific topics that interested me</p>
</li>
</ul>
<p>Total time to "download" the key moments from the 90 minute call: 10 minutes. That's 10 minutes to convert a dataset made up of around 15,000 spoken words to a machine-readable format, and to then digest, analyze, and summarize it.</p>
<h3 id="heading-how-to-use-gpt-for-business-analytics">How to Use GPT for Business Analytics</h3>
<p>But all that's old news by now. The <em>next-level</em> level will solve the problem of business analytics.</p>
<p>Ok. So what <em>is</em> the "problem with business analytics"? It's the hard work of building sophisticated code that parses large datasets to make them consistently machine readable (also known as "data wrangling"). It then applies complex algorithms to tease out useful insights. The figure below broadly outlines the process.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/gai-8-1.png" alt="A diagram illustrating the data wrangling process" width="600" height="400" loading="lazy"></p>
<p>A lot of the code that fits that description is incredibly complicated, not to mention clever. Inspiring clever data engineers to write that clever code can, of course, cost organizations many, many fortunes. The "problem" then, is the cost.</p>
<p>So solving that problem could involve leveraging a few hundred dollars worth of large language model (LLM) API charges. Here's how I plan to illustrate that.</p>
<p>I'll need a busy spreadsheet to work with, right? The best place I know for good data is the <a target="_blank" href="https://www.kaggle.com/">Kaggle website</a>.</p>
<p>Kaggle is an online platform for hosting datasets (and data science competitions). It's become in important resource for data scientists, machine learning practitioners, and researchers, allowing them to showcase their skills, learn from <a target="_blank" href="https://www.kaggle.com/">others,</a> and collaborate on projects. The platform offers a wide range of public and private datasets, as well as tools and features to support data exploration and modeling.</p>
<h3 id="heading-how-to-prepare-a-dataset">How to Prepare a Dataset</h3>
<p><a target="_blank" href="https://www.kaggle.com/datasets/snassimr/data-for-investing-type-prediction">The "Investing Program Type Prediction"</a> dataset associated with this code should work perfectly. From what I can tell, this was data aggregated by a bank somewhere in the world that represents its customers' behavior.</p>
<p>Everything has been anonymized, of course, so there's no way for us to know which bank we're talking about, who the customers were, or even where in the world all this was happening. In fact, I'm not even 100% sure what each column of data represents.</p>
<p>What <em>is</em> clear is that each customer's age and neighborhood are there. Although the locations have been anonymized as <code>C1</code>, <code>C2</code>, <code>C3</code> and so on, some of the remaining columns clearly contain financial information.</p>
<p>Based on those assumptions, my ultimate goal is to search for statistically valid relationships between columns. For instance, are there specific demographic features (income, neighborhood, age) that predict a greater likelihood of a customer purchasing additional banking products? For this specific example I'll see if I can identify the geographic regions within the data whose average household wealth is the highest.</p>
<p>For normal uses, such vaguely described data would be worthless. But since we're just looking to demonstrate the process it'll do just fine. I'll <em>make up</em> column headers that more or less fit the shape of their data. Here's how I named them:</p>
<ul>
<li><p>Customer ID</p>
</li>
<li><p>Customer age</p>
</li>
<li><p>Geographic location</p>
</li>
<li><p>Branch visits per year</p>
</li>
<li><p>Total household assets</p>
</li>
<li><p>Total household debt</p>
</li>
<li><p>Total investments with bank</p>
</li>
</ul>
<p>The column names need to be very descriptive because those will be the only clues I'll give GPT to help it understand the data. I did have to add my own customer IDs to that first column (they didn't originally exist).</p>
<p>The fastest way I could think of to do that was to insert the <code>=(RAND())</code> formula into the top data cell in that column (with the file loaded into spreadsheet software like Excel, Google Sheets, or LibreOffice Calc) and then apply the formula to the rest of the rows of data. When that's done, all the 1,000 data rows will have unique IDs, albeit IDs between 0 and 1 with many decimal places.</p>
<h3 id="heading-how-to-apply-llamaindex-to-the-problem">How to Apply LlamaIndex to the Problem</h3>
<p>With my data prepared, I'll use <a target="_blank" href="https://www.llamaindex.ai/">LlamaIndex</a> to get to work analyzing the numbers. As before, the code I'm going to execute will:</p>
<ul>
<li><p>Import the necessary functionality</p>
</li>
<li><p>Add my OpenAI API k<a target="_blank" href="https://www.llamaindex.ai/">ey</a></p>
</li>
<li><p>Read the data file that's in the directory called <code>data</code></p>
</li>
<li><p>Build the nodes from which we'll populate our index</p>
</li>
</ul>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> openai
<span class="hljs-keyword">from</span> llama_index <span class="hljs-keyword">import</span> SimpleDirectoryReader
<span class="hljs-keyword">from</span> llama_index.node_parser <span class="hljs-keyword">import</span> SimpleNodeParser
<span class="hljs-keyword">from</span> llama_index <span class="hljs-keyword">import</span> GPTVectorStoreIndex

os.environ[<span class="hljs-string">'OPENAI_API_KEY'</span>] = <span class="hljs-string">"sk-XXXX"</span>

documents = SimpleDirectoryReader(<span class="hljs-string">'data'</span>).load_data()
parser = SimpleNodeParser()
nodes = parser.get_nodes_from_documents(documents)
index = GPTVectorStoreIndex.from_documents(documents)
</code></pre>
<p>Finally, I'll send my prompt:</p>
<pre><code class="lang-python">response = index.query(
    <span class="hljs-string">"Based on the data, which 5 geographic regions had the highest average household net wealth? Show me nothing more than the region codes"</span>
)
print(response)
</code></pre>
<p>Here it is again in a format that's easier on the eyes:</p>
<blockquote>
<p><em>Based on the data, which 5 geographic regions had the highest household net wealth?</em></p>
</blockquote>
<p>I asked this question primarily to confirm that GPT understood the data. It's always good to test your model just to see if the responses you're getting seem to reasonably reflect what you already know about the data.</p>
<p>To answer properly, GPT would need to figure out what each of the column headers means and the relationships <em>between</em> columns. In other words, it would need to know how to calculate net worth for each row (account ID) from the values in the <code>Total household assets</code>, <code>Total household debt</code>, and  <code>Total investments with bank</code> columns. It would then need to aggregate all the net worth numbers that it generated by <code>Geographic location</code>, calculate averages for each location and, finally, compare all the averages and rank them.</p>
<p>The result? I <em>think</em> GPT nailed it. After a minute or two of deep and profound thought (and around $0.25 in API charges), I was shown five location codes (G0, G90, G96, G97, G84, in case you're curious). This tells me that GPT understands the location column the same way I did and is at least attempting to infer relationships between location and demographic features.</p>
<p>What did I mean "I think"? Well I never actually checked to confirm that the numbers made sense. For one thing, this isn't real data anyway and, for all I know, I guessed the contents of each column incorrectly.</p>
<p>But also because <em>every</em> data analysis needs checking against the real world so, in that sense, GPT-generated analysis is no different. In other words, whenever you're working with data that's supposed to represent the real world, you should always find a way to calibrate your data using known values to confirm that the whole thing isn't a happy fantasy.</p>
<p>I then asked a second question that reflects a real-world query that would interest any bank:</p>
<blockquote>
<p><em>Based on their age, geographic location, number of annual visits to bank branch, and total current investments, who are the ten customers most likely to invest in a new product offering? Show me only the value of the</em> <code>customer ID</code> columns for those ten customers.</p>
</blockquote>
<p>Once again GPT spat back a response that at least <em>seemed</em> to make sense. This question was also designed to test GPT on its ability to correlate multiple metrics and submit them to a complex assessment ("...most likely to invest in a new product offering").</p>
<p>I'll rate that as another successful experiment.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>GPT – and other LLMs – are capable of independently parsing, analyzing, and deriving insights from large data sets.</p>
<p>There will be limits to the magic, of course. GPT and its cousins can still hallucinate – especially when your prompts give it too much room to be "creative" or, sometimes, when you've been gone too deep into a single prompt thread. And there are also some hard limits to how much data OpenAI will allow you to upload.</p>
<p>But, overall, you can accomplish more and faster than you can probably imagine right now.</p>
<p>While all that greatly simplifies the data analytics process, success still depends on understanding the real-world context of your data and coming up with specific and clever prompts. That'll be your job.</p>
<p><em>This article is excerpted from</em> <a target="_blank" href="https://amzn.to/3yLFT3b"><em>my Manning book, The Complete Obsolete Guide to Generative AI.</em></a> <em>There's plenty more technology goodness available through</em> <a target="_blank" href="https://bootstrap-it.com"><em>my website</em></a><em>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Where Data Science meets Sports Analytics with Ken Jee [Podcast Interview #135] ]]>
                </title>
                <description>
                    <![CDATA[ On this week's episode of the podcast, I interview Ken Jee. Ken's a Data Scientist. He's also a Sports Analytics practitioner who works with US Team Golf and USA Basketball. Ken hosts the excellent Ken's Nearest Neighbors podcast and the Exponential ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/where-data-science-meets-sports-analytics-with-ken-jee-podcast-interview-135/</link>
                <guid isPermaLink="false">66ace689028fa1067f03a05b</guid>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Data Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ sports ]]>
                    </category>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Fri, 02 Aug 2024 14:00:41 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722162236835/5e458f87-0c04-44a3-a601-007ee03d713f.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>On this week's episode of the podcast, I interview Ken Jee. Ken's a Data Scientist. He's also a Sports Analytics practitioner who works with US Team Golf and USA Basketball.</p>
<p>Ken hosts the excellent Ken's Nearest Neighbors podcast and the Exponential Athelete podcast.</p>
<p>We talk about:</p>
<ul>
<li><p>How an injury pushed Ken out of pro sports and into data science</p>
</li>
<li><p>How Ken explains his statistical insights to coaches and players to help them improve their performance</p>
</li>
<li><p>Why Ken doesn't think building projects is all that useful anymore. "Data Scientists should instead build products."</p>
</li>
<li><p>How Ken starts and ends each day with meditation, and writes down all the ideas that pop into his head after each session.</p>
</li>
<li><p>Ken's observation that: "Who is the best suited to excel in a world where AI tools are prominent? Probably the people who are building them. People in the data science domain, people who are coding – they're the most prepared to use these tools for other things."</p>
</li>
</ul>
<p>Can you guess what song I'm playing on my bass during the intro? It's from a 2006 dance song, and it was originally played on a synth.</p>
<p>Also, I want to thank the 9,779 kind people who support our charity each month, and who make this podcast possible. You can join them and support our mission at: <a target="_blank" href="https://www.freecodecamp.org/donate">https://www.freecodecamp.org/donate</a></p>
<p>You can watch the interview on YouTube:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/y8owE6swaLw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Or you can listen to the podcast in Apple Podcasts, Spotify, or your favorite podcast app. Be sure to follow the freeCodeCamp Podcast there so you'll get new episodes each Friday.</p>
<p>Links we talk about during our conversation:</p>
<p>Ken's Nearest Neighbors Podcast: <a target="_blank" href="https://www.youtube.com/channel/UCpEJMMRoTIHJ8vG8q_EwqCg">https://www.youtube.com/channel/UCpEJMMRoTIHJ8vG8q_EwqCg</a></p>
<p>The Exponential Athelete Podcast, also hosted by Ken: <a target="_blank" href="https://www.youtube.com/playlist?list=PLAkSd12rP282takuFJKsAsYlHdpdEDhuE">https://www.youtube.com/playlist?list=PLAkSd12rP282takuFJKsAsYlHdpdEDhuE</a></p>
<p>The Founders podcast, which both Ken and Quincy listen to. James Dyson episode: <a target="_blank" href="https://www.founderspodcast.com/episodes/88384801/senra-james-dyson-against-the-odds-an-autobiography">https://www.founderspodcast.com/episodes/88384801/senra-james-dyson-against-the-odds-an-autobiography</a></p>
<p>Anna Wintour episode: <a target="_blank" href="https://www.founderspodcast.com/episodes/58741411/senra-326-anna-wintour">https://www.founderspodcast.com/episodes/58741411/senra-326-anna-wintour</a></p>
<p>San Antonio caves that Quincy visited: <a target="_blank" href="https://naturalbridgecaverns.com/">https://naturalbridgecaverns.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Grafana on EC2 ]]>
                </title>
                <description>
                    <![CDATA[ In today's data-driven world, it's important to monitor and visualize system metrics to make sure everything works consistently and performs well.  Grafana is an open-source analytics and monitoring platform. It has gained widespread recognition amon... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-grafana-on-ec2/</link>
                <guid isPermaLink="false">66ba0c6be272700c6e2ec43d</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Grafana ]]>
                    </category>
                
                    <category>
                        <![CDATA[ monitoring ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Onwubiko Emmanuel ]]>
                </dc:creator>
                <pubDate>Fri, 02 Aug 2024 13:42:27 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/08/pexels-kawserhamid-176342.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In today's data-driven world, it's important to monitor and visualize system metrics to make sure everything works consistently and performs well. </p>
<p>Grafana is an open-source analytics and monitoring platform. It has gained widespread recognition among developers and enterprises looking to extract more insights from the data produced by their systems. </p>
<p>Grafana has many powerful visualization features, and when combined with Amazon EC2's scalability and flexibility, it creates a stable environment for efficient monitoring. </p>
<p>This article will walk you through setting up Grafana on Amazon EC2 and creating informative dashboards out of raw data. </p>
<h2 id="heading-for-whom-is-this-intended"><strong>For Whom is this Intended?</strong></h2>
<p>This tutorial is intended for both novices to the cloud and experts in DevOps. The goal of this post is to make the installation process easier so you can use Grafana on AWS to its fullest. Now let's get going.</p>
<h2 id="heading-how-to-configure-your-ec2-instance"><strong>How to Configure Your EC2 Instance</strong></h2>
<p>You need to configure the inbound rule for your EC2 instance to access port 3000, as Grafana operates on this port. But first, you need to establish an EC2 instance. You can follow this guide on how to set up your <a target="_blank" href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html">AWS EC2</a> instance. It takes less than 5 minutes.</p>
<p>Once you have created your EC2 instance, you'll need to configure the network inbound rules. So head to your instance page and click on it. On the button widget, click on the <strong>security</strong> tab and click on the security group link (it should look like this: “<strong>sg-547<strong><strong><strong><strong><em>**</em></strong></strong></strong></strong></strong>”). </p>
<p>Once you open the page in the inbound rules section, click on ‘<strong>Edit inbound rules</strong>’. Click on Add a new rule and add <strong>3000</strong> to the port range field, and on the source field, select <strong>0.0.0.0/0.</strong> Then save.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721347239653_image.png" alt="Image" width="1024" height="162" loading="lazy">
<em>Inbound rules</em></p>
<h2 id="heading-how-to-create-an-iam-role"><strong>How to Create an IAM Role</strong></h2>
<p>Now you need to construct an <strong>IAM (Identity Access Management)</strong> role. You're developing an identity role so that you can generate credentials that you'll subsequently use to log in to your Grafana service.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721348061199_IAM+Dashboard.png" alt="Image" width="1912" height="876" loading="lazy">
<em>IAM Dashboard</em></p>
<p>So, in the search field, type "<strong>IAM service</strong>" and click it. Click '<strong>Create role</strong>', and select the AWS service as the trusted entity type.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721348079999_IAM+Role+creation.png" alt="Image" width="1893" height="865" loading="lazy">
<em>IAM Trusted Entity</em></p>
<p>On the use case section, select EC2, then click next.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721348098668_EC2+Use+Case.png" alt="Image" width="1906" height="877" loading="lazy">
<em>IAM role use case</em></p>
<p>On the Add Permissions page, click on the <strong>AdministratorAccess</strong> policy, then click next. Enter a role name – in this case, I used <strong>Grafana-Server-Role.</strong></p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721348120427_IAM+role+modify+.png" alt="Image" width="1916" height="835" loading="lazy">
<em>Role creation</em></p>
<h2 id="heading-how-to-download-grafana">How to Download Grafana</h2>
<p>Now that you've configured your EC2 inbound rule and also configured the IAM role, let's set up Grafana on your EC2 instance. </p>
<p>So head over to <a target="_blank" href="https://grafana.com/grafana/download">Grafana's download page</a>. Since we'll be downloading the version for Amazon Linux in this tutorial, you need to type in the following command on your Linux command line. Note: You need to connect to your VM instance through SSH (Secure Shell). In this case, I am using the EC2 Instance Connect.</p>
<pre><code class="lang-bash">sudo yum install -y https://dl.grafana.com/enterprise/release/grafana-enterprise-11.1.0-1.x86_64.rpm
</code></pre>
<p>Now you'll enable the Grafana service on your terminal by typing the following command:</p>
<pre><code class="lang-bash">systemctl <span class="hljs-built_in">enable</span> grafana-server.service
</code></pre>
<p>Then start the service:</p>
<pre><code class="lang-bash">systemctl start grafana-server.service
</code></pre>
<p>Check the status of the Grafana service on the EC2 instance by running this command:</p>
<pre><code class="lang-bash">systemctl status grafana-server.service
</code></pre>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721411484886_Grafana+Active+.png" alt="Image" width="1101" height="175" loading="lazy">
<em>Grafana Service Status</em></p>
<p>Now that you've confirmed that the service is currently active, you'll also need to check if the Grafana service is active on <strong>port 3000</strong>, as you've already created an inbound rule to cater for this. </p>
<p>You can do this by typing the following command:</p>
<pre><code class="lang-bash">netstat -tunpl | grep grafana
</code></pre>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721411578753_3000+active.png" alt="Image" width="1107" height="22" loading="lazy">
<em>Port 3000 confirmation</em></p>
<p>Now that you've confirmed that the service runs on port 3000, you can go ahead and set up your Grafana dashboard.</p>
<p>You can access the Grafana dashboard by typing the Public IP of your EC2 instance and adding port 3000 on your web browser, something like this: <strong>34.239.101.172:3000</strong>.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721411871355_Grafana.png" alt="Image" width="1877" height="931" loading="lazy">
<em>Grafana Login</em></p>
<p>The default username and password for Grafana are admin, but you'll be given the option to change your password after you sign in with the default credentials. You can also skip the password change process if you like.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721412805910_Grafana+Password.png" alt="Image" width="1902" height="927" loading="lazy">
<em>Change password on Grafana</em></p>
<p>After this step, go to the home page. The next thing to do is to start connecting your Grafana dashboard to a data source. In this case, you're going to connect it to the AWS cloud watch service.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721413426627_Grafana+home.png" alt="Image" width="1918" height="907" loading="lazy">
<em>Grafana</em></p>
<h2 id="heading-how-to-connect-data-sources-to-the-grafana-dashboard"><strong>How to Connect Data Sources to the Grafana Dashboard</strong></h2>
<p>Click on the connections tab on the side menu and click on data sources. Search for the CloudWatch service.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721413905866_image.png" alt="Image" width="1361" height="646" loading="lazy">
<em>Cloudwatch configuration</em></p>
<p>Now you'll be prompted to input your access key ID and secret access key. You will need to create this on your AWS IAM service. </p>
<p>So go back to your IAM management dashboard and go to the user's tab. If you haven’t created an IAM user, you can do so by checking out this <a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html">IAM user creation tutorial</a>. </p>
<p>In the user IAM dashboard, scroll down to the access keys section and click on <strong>Create access key.</strong></p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721414737862_Access+Key.png" alt="Image" width="1447" height="277" loading="lazy">
<em>Access key</em></p>
<p>Select the Command Line Interface use case.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721414696820_Access+Key+2.png" alt="Image" width="1917" height="876" loading="lazy">
<em>Access key use case</em></p>
<p>Set the description tag. This step is optional. Then click on the <strong>Create access key.</strong></p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721414844084_Access+Key+3.png" alt="Image" width="1787" height="738" loading="lazy">
<em>Access keys</em></p>
<p>Now copy the Access Key ID and Secret access key and paste them into the CloudWatch Datasource configuration page on Grafana. Set your default cloud region – in this case, mine is <strong>us-east-1</strong></p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721414955923_image.png" alt="Image" width="558" height="260" loading="lazy">
<em>Additional settings</em></p>
<p>When you’re done, click on the save and test buttons. Grafana will query the Cloudwatch logs, and if it works fine it will save the configuration.</p>
<h2 id="heading-how-to-create-a-dashboard-on-grafana"><strong>How to Create a Dashboard on Grafana</strong></h2>
<p>Now that you have successfully configured your grafana service, let’s start creating dashboards.</p>
<p>Click on the dashboard tab on the side menu click on <strong>New</strong> and select new dashboard. You should see the screen below:</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721416576260_dashboard.png" alt="Image" width="1910" height="928" loading="lazy">
<em>Create a new dashboard</em></p>
<p>Then select <strong>Import dashboard.</strong></p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721417832804_image.png" alt="Image" width="1354" height="643" loading="lazy">
<em>Import a dashboard</em></p>
<p>For this case, you'll be importing an already-made dashboard from Grafana. Grafana has a lot of dashboards for a lot of use cases and services. But in this case, you'll be importing an EC2 dashboard (<a target="_blank" href="https://grafana.com/grafana/dashboards/11265-amazon-ec2/">Grafana EC2 dashboard</a>). </p>
<p>If you want to import it, you can easily copy the ID of the dashboard that you want to import. It is always accompanied by the dashboard.</p>
<p>So now copy the ID – in this case, it's <strong>11265</strong>. Then paste it into the import field on the import dashboard, and click on the load button.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4B51535633ABB1D019D79F3934180D191EF4BB549B6DD5EF46643EA16E05EAAE_1721418236847_Grafana+Dashboard.png" alt="Image" width="1912" height="927" loading="lazy">
<em>Grafana Dashboard</em></p>
<p>Now you have successfully created a dashboard in Grafana. This dashboard lets you monitor the performance of your EC2 instance. You can monitor metrics such as CPU Utilization, CPU Credit, Disk Ops, Disk Bytes, Network, Network Packets, Status check, and so on.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Thank you for reading! I hope this step by step guide has helped you learn how to create and set up efficient dashboards using Grafana. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add Google Analytics to your Astro Website ]]>
                </title>
                <description>
                    <![CDATA[ You can use data insights derived from your website or app to make important decisions that'll help grow your business. This information can help you improve user experience, create effective content strategies, and so on. Google Analytics is an effe... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-google-analytics-to-your-astro-website/</link>
                <guid isPermaLink="false">66b0a2bfb30dd4d00547bb92</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Astro ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Analytics ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ihechikara Abba ]]>
                </dc:creator>
                <pubDate>Wed, 18 Oct 2023 18:07:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/10/andy-hermawan-bVBvv5xlX3g-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You can use data insights derived from your website or app to make important decisions that'll help grow your business. This information can help you improve user experience, create effective content strategies, and so on.</p>
<p>Google Analytics is an effective tool for tracking and analyzing traffic and events on your websites and mobile apps. In this article, you'll learn how to add Google Analytics to your Astro website.</p>
<p>To follow along, you'll need the following:</p>
<ul>
<li>A Google account.</li>
<li>A deployed Astro project.</li>
</ul>
<p>Let's get started!</p>
<h2 id="heading-how-to-add-google-analytics-to-an-astro-website">How to Add Google Analytics to an Astro Website</h2>
<p>Before adding Google analytics, make sure you've already deployed your project. Here's one that I've deployed using Netlify: <a target="_blank" href="https://astro-article.netlify.app/">https://astro-article.netlify.app/</a>. This is an Astro blog template created with the <code>npm create astro@latest -- --template blog</code> command.</p>
<p>This section will be divided into two sub-sections. In the first sub-section, you'll learn how to create an Analytics account and how to set up your account for tracking and monitoring your website.</p>
<p>In the second sub-section, you'll learn how to configure your code to sync with Google Analytics.</p>
<h3 id="heading-how-to-set-up-google-analytics">How to Set Up Google Analytics</h3>
<p>You can follow these steps to set up Google Analytics:</p>
<h4 id="heading-step-1-account-creation-page">Step #1 – Account Creation Page</h4>
<p>The first step is to create a Google Analytics account. You can do that by visiting <a target="_blank" href="https://analytics.google.com/">the Google Analytics website</a>.</p>
<p>When the page loads, you should see something similar to this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/google-analytics-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Google Analytics home page</em></p>
<p>Click on the "Start measuring" button. This will take you to the account creation page where you'll fill in some info about your website/app. That is:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/account-creation.png" alt="Image" width="600" height="400" loading="lazy">
<em>"Create an Account" page on Google Analytics</em></p>
<p>After inputting an account name, scroll down the page and click on the "Next" button.</p>
<h4 id="heading-step-2-property-creation-page">Step #2 – Property Creation Page</h4>
<p>On the property creation page, you can create a property name, time zone, and currency.</p>
<p>A property acts as a unique identifier for your websites and apps. So it is like a container for all the data related to a specified website or app.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/property-creation.png" alt="Image" width="600" height="400" loading="lazy">
<em>"Create a Property" page on Google Analytics</em></p>
<h4 id="heading-step-3-business-details-page">Step #3 – Business Details Page</h4>
<p>On the business details page, you can specify your industry category and the business size.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/business-details.png" alt="Image" width="600" height="400" loading="lazy">
<em>"Describe your business" page on Google Analytics</em></p>
<h4 id="heading-step-4-business-objectives-page">Step #4 – Business Objectives Page</h4>
<p>The business objectives helps Analytics generate personalized reports for your business. You can select the options that are important to your website, app, or product category.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/business-objectives.png" alt="Image" width="600" height="400" loading="lazy">
<em>"Business objectives" page on Google Analytics</em></p>
<p>After selecting the options, click on the "Create" button.</p>
<h4 id="heading-step-5-data-collection-page">Step #5 – Data Collection Page</h4>
<p>On the data collection page, you can choose between different platforms to collect data from. Since we're working with a website, we'll go with the Web option.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/data-collection.png" alt="Image" width="600" height="400" loading="lazy">
<em>"Start collecting data" page on Google Analytics</em></p>
<p>Next, you'll have to create a data stream by inputting your website URL and your stream name (this can be whatever you want, but I'll recommend using a name related to your website).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/stream.png" alt="Image" width="600" height="400" loading="lazy">
<em>Page to setup a data stream on Google Analytics</em></p>
<p>In my data stream information, I used <a target="_blank" href="https://astro-article.netlify.app/">https://astro-article.netlify.app/</a> as the URL and "Astro Blog Template" as the stream name. </p>
<p>Make sure you remove the "https://" part of the link in the input box so you don't get the "Valid website URL is required" error. </p>
<p>So instead of <a target="_blank" href="https://astro-article.netlify.app/">https://astro-article.netlify.app/</a>, it should be astro-article.netlify.app/.</p>
<p>This is what mine looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/stream-data.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example of information entered properly in data stream setup page</em></p>
<p>Go ahead and click on the "Create stream" button.</p>
<p>On the next page/prompt, you'll see your stream name, URL, ID, and measurement ID values. </p>
<p>The measurement ID will be important in our code integration so you can copy and paste it somewhere.</p>
<p>Here's what the page looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/stream-details.png" alt="Image" width="600" height="400" loading="lazy">
<em>"Web stream details" page on Google Analytics</em></p>
<p>If you click on "View tag instructions", you'll see a code snippet for manual integration with code. Copy the code and paste somewhere because we'll make use of it soon.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/installation-instructions.png" alt="Image" width="600" height="400" loading="lazy">
<em>Installation instructions</em></p>
<p>Here's the code snippet if you missed it:</p>
<pre><code class="lang-js">&lt;!-- Google tag (gtag.js) --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">async</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://www.googletagmanager.com/gtag/js?id=MEASUREMENT_ID"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-built_in">window</span>.dataLayer = <span class="hljs-built_in">window</span>.dataLayer || [];
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">gtag</span>(<span class="hljs-params"></span>)</span>{dataLayer.push(<span class="hljs-built_in">arguments</span>);}
  gtag(<span class="hljs-string">'js'</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>());

  gtag(<span class="hljs-string">'config'</span>, <span class="hljs-string">'MEASUREMENT_ID'</span>);
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<p>If you're copying the code above, make sure you replace the two <code>MEASUREMENT_ID</code> values with the actual value of your measurement ID.</p>
<h3 id="heading-how-to-integrate-google-analytics-and-astro">How to Integrate Google Analytics and Astro</h3>
<p>At this point, we've created a Google Analytics account and generated our project's measurement ID. The next thing to do is to sync our code to Google Analytics.</p>
<p>But first, we have to install a library called Partytown. When using third party integrations, you may run into performance issues because you're making use of third-party code.</p>
<p>Partytown allows these integrations to run as expected without reducing your site's performance. You can read more about that <a target="_blank" href="https://partytown.builder.io/how-does-partytown-work">here</a>.</p>
<h4 id="heading-step-1-install-partytown">Step #1 – Install Partytown</h4>
<p>Head to your Astro project terminal and run this command to install Partytown:</p>
<pre><code class="lang-bash">npm install @astrojs/partytown
</code></pre>
<h4 id="heading-step-2-configure-partytown">Step #2 – Configure Partytown</h4>
<p>After the installation is complete, you'll need to add the integration to your <strong>astro.config.mjs</strong> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { defineConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">'astro/config'</span>;
<span class="hljs-keyword">import</span> mdx <span class="hljs-keyword">from</span> <span class="hljs-string">'@astrojs/mdx'</span>;
<span class="hljs-keyword">import</span> partytown <span class="hljs-keyword">from</span> <span class="hljs-string">'@astrojs/partytown'</span>

<span class="hljs-keyword">import</span> sitemap <span class="hljs-keyword">from</span> <span class="hljs-string">'@astrojs/sitemap'</span>;

<span class="hljs-comment">// https://astro.build/config</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> defineConfig({
    <span class="hljs-attr">site</span>: <span class="hljs-string">'https://astro-article.netlify.app/'</span>,
    <span class="hljs-attr">integrations</span>: [
        mdx(), 
        sitemap(),
        partytown({
            <span class="hljs-attr">config</span>: {
              <span class="hljs-attr">forward</span>: [<span class="hljs-string">"dataLayer.push"</span>],
            },
        }),
    ],
});
</code></pre>
<p>In the code above, we imported the Partytown library: <code>import partytown from '@astrojs/partytown'</code>.</p>
<p>We then added this piece of code to the <code>integrations</code> object:</p>
<pre><code class="lang-js">partytown({
      <span class="hljs-attr">config</span>: {
        <span class="hljs-attr">forward</span>: [<span class="hljs-string">"dataLayer.push"</span>],
      },
})
</code></pre>
<p>Everything else in the code came with the Astro project.</p>
<h4 id="heading-step-3-add-google-tag-to-your-pages">Step #3 – Add Google Tag to your Pages</h4>
<p>Remember the code snippet from Google Analytics? This is where we'll use it.</p>
<pre><code class="lang-js">&lt;!-- Google tag (gtag.js) --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/partytown"</span> <span class="hljs-attr">async</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://www.googletagmanager.com/gtag/js?id=MEASUREMENT_ID"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/partytown"</span>&gt;</span><span class="javascript">
  <span class="hljs-built_in">window</span>.dataLayer = <span class="hljs-built_in">window</span>.dataLayer || [];
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">gtag</span>(<span class="hljs-params"></span>)</span>{dataLayer.push(<span class="hljs-built_in">arguments</span>);}
  gtag(<span class="hljs-string">'js'</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>());

  gtag(<span class="hljs-string">'config'</span>, <span class="hljs-string">'MEASUREMENT_ID'</span>);
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<p>Note that we added the <code>type="text/partytown"</code> attribute to both <code>&lt;script&gt;</code> tags.</p>
<p>Remember to change the <code>MEASUREMENT_ID</code> values to the value of your measurement ID. Mine looks like this:</p>
<pre><code class="lang-js">&lt;!-- Google tag (gtag.js) --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/partytown"</span> <span class="hljs-attr">async</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://www.googletagmanager.com/gtag/js?id=G-KM36S70L8Y"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/partytown"</span>&gt;</span><span class="javascript">
    <span class="hljs-built_in">window</span>.dataLayer = <span class="hljs-built_in">window</span>.dataLayer || [];
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">gtag</span>(<span class="hljs-params"></span>)</span>{dataLayer.push(<span class="hljs-built_in">arguments</span>);}
    gtag(<span class="hljs-string">'js'</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>());

    gtag(<span class="hljs-string">'config'</span>, <span class="hljs-string">'G-KM36S70L8Y'</span>);
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<p>Do not use the snippet above as it has my measurement ID so it's already associated with my website (not my actual website :)). Copy the first code snippet and change the <code>MEASUREMENT_ID</code> values to the value of your measurement ID.</p>
<p>To track and monitor a page, you need to paste the code snippet in that page. Copy the code and paste it in the <code>&lt;head&gt;</code> section of every page file (<strong>index.astro</strong>, <strong>BlogPost.astro</strong>, and so on) you want to track and analyze using Google Analytics.</p>
<p>Here's an example using the <strong>index.astro</strong> file in the <strong>pages</strong> directory:</p>
<pre><code class="lang-js">---
<span class="hljs-keyword">import</span> BaseHead <span class="hljs-keyword">from</span> <span class="hljs-string">'../components/BaseHead.astro'</span>;
<span class="hljs-keyword">import</span> Header <span class="hljs-keyword">from</span> <span class="hljs-string">'../components/Header.astro'</span>;
<span class="hljs-keyword">import</span> Footer <span class="hljs-keyword">from</span> <span class="hljs-string">'../components/Footer.astro'</span>;
<span class="hljs-keyword">import</span> { SITE_TITLE, SITE_DESCRIPTION } <span class="hljs-keyword">from</span> <span class="hljs-string">'../consts'</span>;
---

&lt;!doctype html&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Google tag (gtag.js) --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/partytown"</span> <span class="hljs-attr">async</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://www.googletagmanager.com/gtag/js?id=MEASUREMENT_ID"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/partytown"</span>&gt;</span><span class="javascript">
            <span class="hljs-built_in">window</span>.dataLayer = <span class="hljs-built_in">window</span>.dataLayer || [];
            <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">gtag</span>(<span class="hljs-params"></span>)</span>{dataLayer.push(<span class="hljs-built_in">arguments</span>);}
            gtag(<span class="hljs-string">'js'</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>());

            gtag(<span class="hljs-string">'config'</span>, <span class="hljs-string">'MEASUREMENT_ID'</span>);
        </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">BaseHead</span> <span class="hljs-attr">title</span>=<span class="hljs-string">{SITE_TITLE}</span> <span class="hljs-attr">description</span>=<span class="hljs-string">{SITE_DESCRIPTION}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
... <span class="hljs-comment">&lt;!-- The rest of the HTML code --&gt;</span></span>
</code></pre>
<p>In the code above, we put the code from Google Analytics in the <code>&lt;head&gt;</code> tag. You can do this for all the pages you want to track and monitor.</p>
<p>Remember to add the  <code>type="text/partytown"</code> attribute to the <code>&lt;script&gt;</code> tags, and to change <code>MEASUREMENT_ID</code> (used in two places in the snippet) to the value of your measurement ID.</p>
<h4 id="heading-step-4-build-and-deploy-your-project">Step #4 – Build and Deploy your Project</h4>
<p>Deploy your project using your preferred process.</p>
<p>In my case, I use <code>npm run build</code> to build into the <strong>dist</strong> folder, and then push the code to GitHub. This automatically triggers a Netlify deployment.</p>
<p>You don't have to use my method, but make sure your project builds before deployment.</p>
<p>Once your website has been deployed, you may have to wait up to 48 hours to start seeing your analytics in the Google Analytics dashboard.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/pending-data-collection.png" alt="Image" width="600" height="400" loading="lazy">
<em>Pending page</em></p>
<p>You'll see this page when you click on the "Continue to Home" button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/analytics-home.png" alt="Image" width="600" height="400" loading="lazy">
<em>Analytics dashboard</em></p>
<p>This is your Analytics dashboard. You can view and analyze your data here when there's data available.</p>
<p>And there you have it! You've successfully integrated your project with Google Analytics.</p>
<h2 id="heading-summary">Summary</h2>
<p>In this article, we saw how to add Google Analytics to an Astro project. This can be used to track and analyze traffic and events on websites and apps.</p>
<p>We saw how to create and set up an Analytics account. </p>
<p>We then saw how to integrate Google Analytics to an Astro project using code.</p>
<p>Happy coding! You can read more Astro tutorials on <a target="_blank" href="https://ihechikara.com/">my blog</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Augmented Analytics? A Definition and Example Use Cases ]]>
                </title>
                <description>
                    <![CDATA[ The term “augmented analytics” has become popular in the business intelligence (BI) and analytics community. But what is augmented analytics? And how can it help managers make better decisions? We'll answer these questions and more. You'll get a mana... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-augmented-analytics-definition-example/</link>
                <guid isPermaLink="false">66b8d68cb0d93ae3e75d91d0</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ marketing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Mon, 04 Apr 2022 04:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/tono-graphy-WtdIwprWnB4-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The term “augmented analytics” has become popular in the business intelligence (BI) and analytics community. But what is augmented analytics? And how can it help managers make better decisions?</p>
<p>We'll answer these questions and more. You'll get a manager-level crash course in augmented analytics. By the end of this article, you should have a solid understanding of what augmented analytics is, and how you can use it to improve your decision making.</p>
<h3 id="heading-what-is-augmented-analytics">What is augmented analytics?</h3>
<p>Augmented analytics is a term used to describe the use of machine learning to automatically analyze data, then provide insights that humans can act on.</p>
<p>It’s sometimes also referred to as “cognitive analytics” or “analytics 2.0.”</p>
<h3 id="heading-how-do-augmented-analytics-work">How do augmented analytics work?</h3>
<p>Augmented analytics rely on machine learning algorithms.</p>
<p>Machine learning is a type of Artificial Intelligence (AI) that allows computers to learn directly from data – without the need for a human to programming them. (That is, there's no need for a human to explicitly tell the computers what to do.)</p>
<p>Machine learning algorithms can automatically detect patterns in data, then use that to make predictions about future events.</p>
<h3 id="heading-what-are-the-benefits-of-augmented-analytics">What are the benefits of augmented analytics?</h3>
<p>There are several benefits of using augmented analytics, including:</p>
<ol>
<li><p><strong>Automation of tedious and time-consuming tasks.</strong> Augmented analytics can automate the more rote aspects of data analysis, freeing managers to focus on the higher-level considerations, including a lot of domain-specific considerations.</p>
</li>
<li><p><strong>Improved accuracy</strong>. By using machine learning algorithms, augmented analytics can provide more accurate insights than humans alone could. Computers are much better at crunching numbers than humans are. And humans are better at interpreting the underlying meaning of those numbers.</p>
</li>
<li><p><strong>Increased speed</strong>. Augmented analytics can help managers make faster decisions by providing real-time insights. Imagine automatically refreshing dashboards that you can reference whenever you need to make a decision.</p>
</li>
<li><p><strong>Increased scalability</strong>. You can easily scale up your augmented analytics to support larger organizations, or incorporate a broader array of data sources.</p>
</li>
</ol>
<h2 id="heading-which-industries-use-augmented-analytics">Which Industries Use Augmented Analytics?</h2>
<p>Here are a few examples of industries that have embraced augmented analytics:</p>
<h3 id="heading-augmented-analytics-in-retail">Augmented Analytics in Retail</h3>
<p>In the retail industry, you can use augmented analytics to automatically analyze customer data and identify trends. If you can anticipate what customers are likely to buy, you can make better decisions about product assortment, pricing, and promotions.</p>
<h3 id="heading-augmented-analytics-in-manufacturing">Augmented Analytics in Manufacturing</h3>
<p>In the manufacturing industry, managers use augmented analytics to automatically analyze data from sensors and machine data to identify issues and optimize production.</p>
<p>Imagine a factory where you know the exact state of every assembly line, the output of every human worker, or even the power usage of individual machines. Imagine being able to identify bottlenecks or waste through real-time dashboards.</p>
<p>There is a lot of room for applying Augmented Analytics tools to save money. So we see manufacturers like Toyota, Apple, and Airbus all making heavy use of these tools.</p>
<h3 id="heading-automated-analytics-in-healthcare">Automated Analytics in Healthcare</h3>
<p>In the healthcare industry, doctors and managers can use augmented analytics to automatically analyze patient data, identify vital sign trends, and improve patient care.</p>
<p>Healthcare in particular has a lot of room for improvement in understanding medical records, and making better decisions based on available data. Augmented Analytics can give hospitals a big leg up.</p>
<h3 id="heading-automated-analytics-in-financial-services">Automated Analytics in Financial Services</h3>
<p>There is perhaps no more obvious use of automated analytics than in finance. Numbers are an intrinsic part of moving money around between investors and companies deploying that money.</p>
<p>Because finance involves money, it is a magnet for fraudulent activity. Automated Analytics can help banks and other parties prevent fraud. They can also help governments prevent money laundering.</p>
<h3 id="heading-automated-analytics-in-marketing">Automated Analytics in Marketing</h3>
<p>Marketers can use augmented analytics to automatically analyze customer data to identify trends and improve marketing campaigns.</p>
<p>When you are spending money on advertising, even marginal refinements can improve your bottom line. </p>
<h3 id="heading-in-short-automated-analytics-can-help-managers-focus-on-what-they-do-best-while-offloading-the-grunt-work-to-computers">In short: Automated Analytics can help managers focus on what they do best, while offloading the grunt work to computers</h3>
<p>Thanks for taking time to read my article. I hope you have fun exploring the world of Automated Analytics. If you're looking to harness technology tools, you can learn some new programming and computer science skills here on freeCodeCamp.org.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use OpenTelemetry to Understand Software Performance ]]>
                </title>
                <description>
                    <![CDATA[ If you want good performance in your application, you need to collect data to figure out where to make improvements. That's where OpenTelemetry comes in. OpenTelemetry offers a single set of APIs and libraries that standardize how you collect and tra... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-opentelemetry/</link>
                <guid isPermaLink="false">66b20368eea9870582e16c66</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Thu, 24 Jun 2021 16:50:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/06/opentelemetry-course.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you want good performance in your application, you need to collect data to figure out where to make improvements. That's where OpenTelemetry comes in.</p>
<p>OpenTelemetry offers a single set of APIs and libraries that standardize how you collect and transfer telemetry data. OpenTelemetry provides a specification for instrumentation so that you can send data to distinct backends of your choice.</p>
<p>We just released a full OpenTelemetry course on the freeCodeCamp.org YouTube channel.</p>
<p>This course was made possible by a grant from <a target="_blank" href="https://www.newrelic.com">New Relic</a>, an observability platform that helps developers monitor and debug their applications.</p>
<p>Ania Kubów created the course. Ania is a popular software educator and she will help you get a full understanding of how to use OpenTelemetry in your projects.</p>
<p>In this course, you will learn how to use OpenTelemetry to get full stack observability on the performance and behavior of your software projects.</p>
<p>Here are the topics covered in this course:</p>
<ul>
<li>What is OpenTelemetry?</li>
<li>What are Microservices?</li>
<li>What is Observability?</li>
<li>M.E.L.T</li>
<li>History</li>
<li>Setting up our Project</li>
<li>What is Tracing?</li>
<li>Context and Propagation</li>
<li>Setting up our Tracing</li>
<li>What are Metrics?</li>
<li>Use cases for OpenTelemetry</li>
<li>Setting up Distributed Tracing</li>
<li>Using other Analysis Tools - New Relic</li>
<li>Where to go next</li>
</ul>
<p>Watch the course below or <a target="_blank" href="https://youtu.be/r8UvWSX3KA8">on the freeCodeCamp.org YouTube channel</a> (1-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/r8UvWSX3KA8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-video-transcript">Video Transcript</h2>
<p>(Autogenerated)</p>
<p>Hello, internet, and welcome to this course all about open telemetry.</p>
<p>In this course, I'm going to be showing you how you can get full stack observability on the performance of the behavior of your software project by using open telemetry with your analysis tool of choice.</p>
<p>If you want to be able to tell why your project or app is running too slow, is broken, or you just want to improve its code quality.</p>
<p>This is the video for you.</p>
<p>But first, what exactly do we mean by over telemetry? Well, let's start off with the name itself, we have open so like open source, and telemetry, which is an institute collection of measurements or other data at remote points.</p>
<p>And that automatic transmission to receiving equipment for monitoring.</p>
<p>The word telemetry actually comes from the Greek root word Teller, or remote, and metron, for measure.</p>
<p>And that's exactly what we are going to be doing, we are going to be facilitating a way to measure the performance of everything we use in our app remotely.</p>
<p>With any app, when you want to start looking at this kind of data, you have two parts that need to come together.</p>
<p>The first is figuring out how to generate and transmit that data.</p>
<p>And then the second part is deciding what you are going to do with that data.</p>
<p>So in other words, how are you going to analyze it? Open telemetry deals with that bus part.</p>
<p>Up until now there has been no real standardized way of describing what your system is doing.</p>
<p>This is down to the fact that we all like to think differently, use different programming languages, different machines, and a combination of different ways.</p>
<p>This was a problem, especially for those wanting to build observability tools.</p>
<p>At the heart of open telemetry project is exactly that, a standardization for describing what distributed systems are doing, no matter what programming language or computer systems you are using.</p>
<p>Today, the open telemetry project can be described as a collection of tools, API's, and SDKs, use it instrument, generate, collect and export telemetry data, so that we can analyze it later on with whatever platform we wish by standardizing our data and means we are not tied to anything in the long run.</p>
<p>And it makes moving from one analysis tool to the next super easy, I will not affect your historic data.</p>
<p>As I mentioned at the beginning, this is an open source project.</p>
<p>It is made up of many, many developers and their inputs.</p>
<p>If we have a look at GitHub here for the project, you will see it is super transparent.</p>
<p>You can see the Governance Committee, you can see the technical committee.</p>
<p>If you are interested in getting involved, please do join their mailing list and attend the community meetings.</p>
<p>You can even see all the meetings that you are welcome to join.</p>
<p>Before we get started, though, I just want to go into a little bit of what we're going to learn on this course.</p>
<p>So let's break it down.</p>
<p>Okay, so in this course, first we're going to look at what are microservices followed by what is observability then we're going to look at melt, followed by the history of open telemetry, then we're going to actually start by setting up a project.</p>
<p>We are then going to talk about tracing, distributed tracing and context and propagation before adding tracing into our project.</p>
<p>We will then move on to looking at metrics before finally ending on our distributed projects.</p>
<p>I will end this course with where to go next.</p>
<p>We expect our websites, apps and online services to load almost instantaneously right? Think of the frustration some of us feel when websites take more than two seconds to load.</p>
<p>on the backend a feat of engineering is needed to keep a global system running to make sure that you have access to Netflix or Instagram.</p>
<p>Only a tap away Let's have a look at Netflix for a minute.</p>
<p>Netflix at its peak consumes 37% of internet bandwidth in the US, there are 1000s of people clicking play at the same time, with activity peaking in the evening.</p>
<p>Though, as a global platform, it's a constant pick.</p>
<p>The challenge is how to run a service with zero loss while processing over 400 billion events daily, and 17 gigabyte per second during peak.</p>
<p>In today's video, we will dive deeper into what types of systems power these amazing services and how we can use data to get deeper visibility into the insights of these complex systems.</p>
<p>Historically, developers about applications in monoliths with large complex code bases, a single monolith will contain all the code for all the business activities and application performed.</p>
<p>This is all fine and dandy if you have a small app.</p>
<p>But what happens if your application turns out to be successful, users will like it and begin to depend on it traffic increases dramatically, and always inevitably use requests improvements and additional features.</p>
<p>So more developers are roped into work on the growing application.</p>
<p>before too long, your application becomes a big ball of mud.</p>
<p>a situation where no single developer understands the entirety of the application.</p>
<p>Your once simple application has now become larger complex.</p>
<p>multiple independent development teams are simulataneously.</p>
<p>Working on the same codebase and simultaneously changing the same sections of code, then it becomes virtually impossible to know who is working on what poetry does collide, code quality suffers, it becomes harder and harder for individual development teams to make changes without having to calculate what the impact will be to other teams and teams can lose sight of how that code might be incompatible with others, among other issues.</p>
<p>This generally results in slower, less reliable applications, not to mention longer and longer development schedules.</p>
<p>In come microservices, the main principle behind a microservice architecture is that the applications are simpler to build and maintain when broken down into smaller pieces.</p>
<p>When using microservices, you isolate software functionality into multiple independent modules that are individually responsible for performing precisely defined standalone tasks.</p>
<p>These modules communicate with each other through simple API's.</p>
<p>microservice architectures let you split applications into distinct independent services, each managed by different teams.</p>
<p>It leads to naturally delegating the responsibilities for building highly scaled applications, allowing work to be done independently on individual services without impacting the work of other developers in other groups working on the same overall application.</p>
<p>However, trying to get visibility into this system can be very difficult.</p>
<p>When you have hundreds of services and applications your request traveled through debugging and troubleshooting can be a nightmare.</p>
<p>This is where open telemetry comes in.</p>
<p>As we already touched on telemetry is defined as the science or process of collecting information about objects that are far away and sending the information somewhere electronically.</p>
<p>Now.</p>
<p>observability means how well you can understand what is going on internally in a system based on its outputs.</p>
<p>Especially as systems become more distributed and complex.</p>
<p>It's hard to see what's going on inside your application and why things may be going wrong.</p>
<p>When talking about observability, we need to define the data types necessary to understand the performance and health of our application broadly, metrics, events, logs and traces.</p>
<p>Met, metrics are measurements collected at regular intervals must have a timestamp and name, one or more numeric values and a count of how many events are represented.</p>
<p>These include error rate, response time or output.</p>
<p>An event is a discrete action happening at any moment in time.</p>
<p>Take a vending machine.</p>
<p>For instance, an event could be the moment when a user makes a purchase from the machine.</p>
<p>Adding metadata to events makes them much more powerful.</p>
<p>With the vending machine example we could add additional attributes such as item category, and payment type.</p>
<p>This allows questions to be asked such as how much money was made from each item category, or what is the most common payment type use.</p>
<p>logs come directly from your app, exporting detailed data and detailed context around an event.</p>
<p>So engineers can recreate what happened millisecond by millisecond.</p>
<p>You have probably logged something when you use things like system out print, or console log traces follow a request from the initial request to the returned output.</p>
<p>It requires the casual chain of events to determine relationships between different entities.</p>
<p>traces are very valuable for highlighting inefficiencies, bottlenecks and roadblocks in the user experience as they can be used to show the end to end latency of individual cores and a distributed architecture.</p>
<p>However, getting that data is very difficult.</p>
<p>You would have to manually instrument every single service one by one layer by layer.</p>
<p>This will take as much time as writing the code itself, which is annoying.</p>
<p>Luckily there are some awesome open source projects as well as companies that make this a lot easier in today's 16 open tracing was released as a cn CF project focused only around distributed tracing.</p>
<p>Because the libraries were lightweight and simple, it could be used to fit any use case.</p>
<p>While it made it easy to instrument data, it made it hard to instrument software that was shipped as binaries without a lot of manual engineering work.</p>
<p>In 2018, a similar project called Open census was open source out of Google, which supported both the capturing retracing permission and metrics.</p>
<p>While it made it easier to get telemetry data from software that was shipped as binaries like Kubernetes, and databases, it made it hard to use the API to instrument custom implementations, not part of the default use case.</p>
<p>Both projects were able to make observability easy for modern applications and expedite wide adoption of distributed tracing by the software industry.</p>
<p>However, developers had to choose between two options with pros and cons.</p>
<p>It turns out that the approaches of the two projects were complimentary rather than contradictory.</p>
<p>There was a no reason why we couldn't have both the abstract vendor neutral API and a well supported default implementation.</p>
<p>In late 2019, the two projects merged to form opentelemetry.</p>
<p>This brought forward the idea of having a single standard for observability instead of two competing standards.</p>
<p>Okay, so first things first, let's go a bit meta and understand exactly what is going to happen.</p>
<p>In order for us to view what is happening in our app.</p>
<p>Here we have our project.</p>
<p>Think about project as a project we have made with our code editors of choice.</p>
<p>For example, if we run it, it runs locally on our machines.</p>
<p>Let's also say this project is built to listen out for requests.</p>
<p>So like listening out for a get request, for example, we have decided that we want to measure our app's performance based on the requests that it makes.</p>
<p>To do this, the first step as we mentioned at the start, would be to implement open telemetry into the project.</p>
<p>We are doing this to help us standardize the data.</p>
<p>Once we have implemented open telemetry and standardize the data, we need to think about what we are going to do with the data, how we're going to view it, and so on.</p>
<p>For this, we can use an analysis tool.</p>
<p>By analysis tool, I mean, any type of tool that gives you observability, we are going to look at a few of these tools, one that focuses specifically on tracing, one that focuses specifically on metrics, and one that looks at everything in one platform.</p>
<p>We are then going to send our data to our analysis tool of choice.</p>
<p>Here we have an example of what our data can look like in a tracing app such as zipkin, a metrics app such as permittees, and an observability tool such as New Relic that will give us an overview of everything as well as other more bespoke insights in one platform.</p>
<p>We will go into each of these in their dedicated sections.</p>
<p>Let's start with implementing open telemetry first.</p>
<p>Okay, so before we start, the only prerequisite I am going to ask of you is that you have Docker downloaded onto your machine.</p>
<p>Docker is a container platform for rapid up microservices development, and delivery.</p>
<p>And if you don't know much about containers and micro services, just stick with me for now.</p>
<p>I have a section dedicated to both of these topics coming up after this section.</p>
<p>For those of you that don't have it, please navigate to the Docker website and follow the instructions.</p>
<p>In order to get set up.</p>
<p>I personally would choose to download the Docker desktop.</p>
<p>As I am working on a Mac, I choose the Mac option.</p>
<p>Once you are done, make sure your Docker desktop is running on a Mac, I would simply hover over the icon like so.</p>
<p>You will see if you open up the platform I currently have no containers running.</p>
<p>Having a container is going to be important for when we get to using the analysis tools, such as a tracing back end like zipkin.</p>
<p>Once we have all got Docker up and running, let's get going.</p>
<p>Let's get our terminal up.</p>
<p>Now I'm going to navigate to a folder where I like to store all my projects.</p>
<p>It's called development.</p>
<p>Please go ahead and choose any directory that you would like to work in.</p>
<p>Now once here using the Mk dir command, I'm going to make a folder for the new project that I'm about to start.</p>
<p>I'm going to call it open telemetry starting out.</p>
<p>Please be aware that if you are using Different terminal, other commands may need to be used.</p>
<p>Now, let's go into the project using the command cd.</p>
<p>The first thing I'm going to do is start our container.</p>
<p>So it's ready for the next section.</p>
<p>So, as mentioned, the first thing that you need before you can start collecting traces is a tracing back end like zipkin, that you can export traces to, to set up zipkin as quickly as possible, run the latest Docker zipkin container, exposing Port 9411.</p>
<p>If you can't, or don't want to run a Docker container, you could also choose to download zipkin directly.</p>
<p>So just so you know, that is an option too.</p>
<p>If you want to explore that option more, I would suggest visiting the zipkin website.</p>
<p>So this is the command to run our container.</p>
<p>And there we go, we now have this container ID, it has worked.</p>
<p>Next up, we need to get a package JSON file in our project, we can do so by typing NPM.</p>
<p>In it, having a package JSON file will make it easier for others to manage and install all the packages we need for the project.</p>
<p>If you are getting errors, it could be because you don't have no js and NPM installed.</p>
<p>If that is the case, please visit node j s.org.</p>
<p>In order to get set up with that by following the download instructions.</p>
<p>Okay, so we have initialized the utility, I am just going to press enter for all these fields, it's prompting me to answer.</p>
<p>So enter and, and, and, and enter.</p>
<p>OK, we are done creating our package JSON file for now.</p>
<p>If we list out all the files on our project, using the ls command, you will see the file right there.</p>
<p>Now finally, I need to create an app js file.</p>
<p>So a JavaScript file and put that in the project to some of you might have a different approach to adding files to a project.</p>
<p>So that is totally up to you, however you'd like to create that file.</p>
<p>But once we are done, we now need to open up our project.</p>
<p>As I am using VS code, I'm going to use the command code.in order to open up our project.</p>
<p>And there we go.</p>
<p>There is a folder with an app js file and a package JSON file.</p>
<p>You will see the package JSON file has all the prompts we were asked, as I skipped all the prompts is just the standard default entries are no entries at all.</p>
<p>If you go to the app js file, you will also see that it's currently empty, it has nothing in it.</p>
<p>Okay, so the first thing I need to do is change this to point to the app js file we created not the index j s as there is no index js file.</p>
<p>And just for fun, this is not necessary, I'm going to fill out the description on my project.</p>
<p>So open telemetry costs.</p>
<p>The next thing I want to do is just add a start script.</p>
<p>So for this script, I'm going to run node app j s.</p>
<p>Okay, now for the fun part, let's get to adding some packages.</p>
<p>To start using open telemetry, we are going to need to install some of its packages.</p>
<p>Using NPM II or install for short.</p>
<p>I'm going to store the open telemetry core package, the open telemetry node package opentelemetry plugin http opentelemetry.</p>
<p>plugin HTTP s, open telemetry exporters zipkin to get us ready for the next section on open telemetry tracing for the next section to an express the only non open telemetry one.</p>
<p>Okay, so we need all of those to install.</p>
<p>Okay, and great.</p>
<p>So these are looking good.</p>
<p>So if we look back here, here are the packages that we just installed.</p>
<p>They have automatically populated our package JSON file.</p>
<p>So this is looking good.</p>
<p>We just missed one.</p>
<p>So let's go back and use NPM II or install for short and install Open telemetry plug in Express.</p>
<p>And we are done.</p>
<p>Okay, now let's move on to our app js file.</p>
<p>The first thing I'm going to do is define a port for us.</p>
<p>So const port, process and V port or a string of Port 8080 Next up, we are going to need Express.</p>
<p>So const Express.</p>
<p>And Express is one of the packages we installed.</p>
<p>So this one right here.</p>
<p>So we need to tell our file that this const requires Express.</p>
<p>We are then going to call Express and stored as the const app.</p>
<p>The first thing I want to do is just get a message in our console log to let us know all is good, and that we are listening out and on which port.</p>
<p>So just as a recap, what I am doing here is getting the app to start a server.</p>
<p>And then with this code, I'm getting it to listen out to our defined port for any requests.</p>
<p>Okay, next up, I'm going to paste this super basic piece of code.</p>
<p>This code is an example of a very basic route.</p>
<p>routing refers to how an applications end points respond to client requests.</p>
<p>We have defined the route using methods of the Express app object that corresponds to http methods.</p>
<p>For example, app get handles GET requests.</p>
<p>These routing methods specify a callback function called when the application receives a request to the specified route an HTTP method.</p>
<p>In other words, it listens out for requests that much specified routes and methods.</p>
<p>In this case, the root is our homepage, we essentially want to trace every single time a get request is made to the homepage.</p>
<p>We will do this in the next section.</p>
<p>Now that we have the basic installation done, it is now time for us to talk about tracing.</p>
<p>So as you know, open telemetry allows us to essentially standardize our data.</p>
<p>The next part is actually viewing the data in a way that we can analyze what is happening behind the scenes, we will do this with a tracing system.</p>
<p>in software engineering tracing involves a specialized use of logging to record information about a program's execution.</p>
<p>This information is typically used by programmers to debug by using the information contained in a trace log to diagnose any problems that might arise with a particular software or app.</p>
<p>Distributed tracing, however, also called a distributed request tracing is a method used to debug and monitor applications built using a micro service architecture.</p>
<p>Distributed tracing helps pinpoint where failures occur, and what causes poor performance.</p>
<p>So as we can now see, being able to get tracing data telemetry is pretty important to the overall performance of an app.</p>
<p>However, as we discussed in the introduction, due to systems using all types of different languages, frameworks and infrastructures, it's a hard thing to do without some sort of common approach.</p>
<p>That's why Evans limitary can help so much with distributed tracing.</p>
<p>By providing a common set of API's, SDKs, and wire protocols.</p>
<p>It gives organizations a single, well supported integration service for end to end distributed tracing telemetry.</p>
<p>For this course, the tracer we're going to be using is called zipkin.</p>
<p>zipkin is a distributed tracing system that helps them gather timing data needed to troubleshoot latency problems and service architectures.</p>
<p>Circuit was originally created by Twitter.</p>
<p>And it's currently run by the open zipkin volunteer organization.</p>
<p>I am using zipkin for no other reason than I had to pick one.</p>
<p>But please do feel free to choose any back end tracing system that you wish, the choice is completely up to you.</p>
<p>In general, once the traces are implemented into applications, they essentially record timing and metadata about operations that take place.</p>
<p>An example of this is when a web server records exactly when it receives a request.</p>
<p>And when it sends a response.</p>
<p>This data is usually represented by a bar, just like this, and goes by the official name of spam.</p>
<p>So in this example, we have two services and a bunch of spans.</p>
<p>To explain this, imagine this represents your favorite food delivery app.</p>
<p>So imagine you make an order right.</p>
<p>Now a few things will happen, each represented by a span.</p>
<p>You send information back and forth from services in order to make the payment, find a delivery driver closest to you, and notify that driver with your order.</p>
<p>Each of these operations generates a spam showing you the work being done to make this happen.</p>
<p>In this case, the spans have implicit relationships, so parent and child but also from individual services and the trace.</p>
<p>As you can see, each of the spans starts at a different point and takes a different amount of time.</p>
<p>We call this latency and network latency.</p>
<p>In a nutshell, latency is delay between an action and a response to that action.</p>
<p>network latency refers to specific delays that take place within a network.</p>
<p>latency is generally measured in milliseconds and is unavoidable due to the way networks communicate with each other.</p>
<p>It depends on several aspects of a network and can vary if any of them are changed.</p>
<p>errors on most systems are usually quite easy to spot.</p>
<p>If your bar ends in red or similar, for example, you know that an error has occurred.</p>
<p>Now it's time for us to look at context and propagation.</p>
<p>These two concepts will allow us to understand the topic of tracing a lot better.</p>
<p>So as we know distributed tracing allows us to correlate events across service boundaries.</p>
<p>But how do we find these correlations for this components in our distributed system need to be able to collect, store and transfer metadata? We refer to this metadata as context.</p>
<p>Context is divided into two types, span context and correlation context.</p>
<p>span context represents the data required for moving trace information across boundaries.</p>
<p>It contains the following metadata.</p>
<p>We have a trace ID, a span ID, the trace flags and the trace state of this bond context.</p>
<p>And then we have the correlation context.</p>
<p>A correlation contacts carries user defined properties.</p>
<p>This is usually things such as a customer ID, providers, hearse name, data region and other telemetry that gives you application specific performance insights.</p>
<p>Correlation context is not required and components may choose to not carry or store this information.</p>
<p>A context will usually have information so we can identify the current span and trace and propagation is the mechanism we use to bundle up our context and transfer across services so that we have it context and propagation.</p>
<p>Together.</p>
<p>These two concepts represent the engine behind distributed tracing.</p>
<p>If you would like to learn more about these two topics and do a deep dive at please visit the urban telemetry website.</p>
<p>For the purpose of this tutorial, however, a basic knowledge above will suffice.</p>
<p>So just as a bit of a heads up in this next section, we will go through how to first initialize a global tracer and after that initialize and register a trace exporter.</p>
<p>Okay, so here we are where we left off.</p>
<p>Now in the last section, we ran the latest Docker zipkin container exposing Port 9411.</p>
<p>If we actually visit localhost 9411, we will see the zipkin UI that comes as part of doing that.</p>
<p>So here we are, this is what we are going to use to view our traces.</p>
<p>Okay, let's carry on.</p>
<p>Next, let's create a file named tracing and j s and add the following code.</p>
<p>This is just the sample code provided to us by opentelemetry.</p>
<p>If you visit their website, you can see I am just copying this code right here and pasting it into my project.</p>
<p>You will also see that this file uses two of the packages we installed in the initial setup.</p>
<p>Once we have pasted that we need to initialize and register a trace exporter.</p>
<p>We have already done part of this as we install two packages necessary for this part and the initial setup section.</p>
<p>And that is the open telemetry tracing and open telemetry export to zipkin packages.</p>
<p>So first off, let's make a new zipkin exporter.</p>
<p>So provide add span processor, new simple span processor.</p>
<p>This is from the open telemetry tracing package, as you can see that has shown up at the top news of can export out.</p>
<p>And that also comes from another package.</p>
<p>So the open telemetry exporters, it can package as you can see appearing at the top, this might not automatically show up for you.</p>
<p>It's just the code editor I'm using.</p>
<p>So you might have to type those two out, and then the right service name and choose a service now.</p>
<p>I'm going to put Getting Started but you can replace it with your own service name.</p>
<p>Okay, that is looking good.</p>
<p>And so is the app js file.</p>
<p>Okay, great.</p>
<p>All tracing in a civilization should happen before your application code runs.</p>
<p>The easiest way to do this is to initialize tracing and a separate file that required using the node r option before your application code runs, I will show you what I mean by this.</p>
<p>So, now, if you run your application with node, our tracing j s and app j s, your application will create and propagate traces over HTTP.</p>
<p>So let's run that.</p>
<p>And now let's send requests to application over HTTP.</p>
<p>We can do so simply by refreshing the localhost 8080 page, you'll see traces exported to our tracing back end, they look like this.</p>
<p>So he will see we are making a get request to the homepage, which is responding with hello world.</p>
<p>And here we have getting started.</p>
<p>As that is what we called our service name.</p>
<p>We also get a start time and a duration as a span.</p>
<p>Now, as you use this more and more often, some spans might appear to be duplicated, but they are not.</p>
<p>This is because some applications can be both the client and the server for these requests.</p>
<p>If this is the case, you will see one span which is the client side request timing, and one span which is the server side request timing, anywhere that they don't overlap is network time.</p>
<p>Okay, now I'm going to show you one more example.</p>
<p>So just to differentiate, I'm going to change my service name to get date.</p>
<p>Now I am going to go into my app js file.</p>
<p>I'm just going to copy this piece of code right here.</p>
<p>And paste.</p>
<p>Now I want to essentially listen out to any time a get request is made to the park date.</p>
<p>So in other words, if someone right now went to localhost 8080 forward slash date, that is us making a get request, we will also be able to see respond with the actual date.</p>
<p>So let's go ahead, let's go back to our localhost 8080 and type forward slash date.</p>
<p>Oops, I stopped my app running, let's make sure it's running.</p>
<p>So I'm just going to start this up again.</p>
<p>Okay, and refresh our page.</p>
<p>And great, there is our object with today's date.</p>
<p>Amazing.</p>
<p>So now if we visit localhost 9411, so the port we exposed, and click run a query, we will see all the requests that have been made.</p>
<p>So there we go, we can now see our get date service.</p>
<p>And at the moment, the only request we have that it's listening out for is the get request.</p>
<p>Now, I have actually renamed the service, remember so if I visit the homepage, you will see that request is also being stored under the get date service name, you can tell which one it is by the timestamp.</p>
<p>Okay, let's move on.</p>
<p>Okay, we are now done with a basic implementation of tracing.</p>
<p>However, we are literally just touching the surface.</p>
<p>In the project portion of our course I will show you how to use open telemetry to instrument a distributed system.</p>
<p>By this I mean I will show you how to trace multiple services and their interactions with each other if those exist.</p>
<p>In this next section, we're going to learn how to collect metrics with open telemetry and remediate Prometheus as a monitoring platform that collects metrics from monitor targets by scraping metrics HTTP endpoints on these targets.</p>
<p>In this section, I will show you how to install, configure and monitor our fast app with Prometheus and open telemetry.</p>
<p>We will download, install and run Prometheus to expose time series data on hosts and services.</p>
<p>Unlike tracing which works in spans metrics are a numeric representation of data measured over intervals of time.</p>
<p>metrics can harness the power of mathematical modeling and prediction to derive knowledge of the behavior of a system over intervals of time in the present and future.</p>
<p>Since numbers are optimized for storage, processing, compression and retrieval, metrics enable longer retention of data as well as easier querying.</p>
<p>This makes metrics perfectly suited to building dashboards that reflect historical trends.</p>
<p>metrics also allow for gradual reduction of data resolution.</p>
<p>After a certain period of time, data can be aggregated into daily or weekly frequency.</p>
<p>Let's have a look at this in action.</p>
<p>In this section, I'm going to be using promethium as my metrics backend.</p>
<p>Now that we have set up end to end traces, we can collect and export some basic metrics.</p>
<p>First, I'm going to stop this from running.</p>
<p>Let's go to the Prometheus download page and download the latest release.</p>
<p>permittees for your operating system.</p>
<p>As I'm using a Mac, I'm going to click on this one right here.</p>
<p>Once that has downloaded open a command line and use CD or the command cd to go into the directory, where you downloaded the promethease tarball.</p>
<p>In my case, it will be the Downloads directory.</p>
<p>Now I need to unretire it into the newly created directory, make sure that you replace the file name with your downloaded harbor.</p>
<p>So don't necessarily use this one.</p>
<p>And now let's go into the directory.</p>
<p>If I list out all the files and folders, you will see a file named permit this yamo this is the file used to configure permit Yes, for now, just make sure permit is start by running the dot four slash promethease binary and the folder and browse to localhost 9090.</p>
<p>Okay, great.</p>
<p>And that is our promethease user interface.</p>
<p>So you will see this as server is ready to receive web requests.</p>
<p>So that should be all good.</p>
<p>I am just going to go ahead and open up a new tab right here so I can keep that running.</p>
<p>And I'm going to open up our directory using the VS code shortcut.</p>
<p>Once we have confirmed that permit the US has started, we need to replace the contents of the primitives yamo file with the following.</p>
<p>So literally just delete everything and put in this much shorter piece of code.</p>
<p>This will set the scrape interval to every 15 seconds.</p>
<p>We are now ready to monitor our Node JS application.</p>
<p>In this next section, we need to initialize the required open telemetry metrics library, initialize a meter and collect metrics and initialize and register a metrics exporter.</p>
<p>To do this, we are going to have to install some libraries, we are going to need the open telemetry metrics package.</p>
<p>So let's go ahead and install that.</p>
<p>Let's navigate back to our project first.</p>
<p>So don't do this in the directory we just downloaded.</p>
<p>And in here, type NPM II or install Open telemetry metrics.</p>
<p>Great, we are now ready to initialize a meter and collect metrics.</p>
<p>We first need a meter to create and monitor metrics a meter and open telemetry is the mechanism used to create and manage metrics, labels, unmetric exporters, create a file named monitoring j s.</p>
<p>So a JavaScript file and the root of your folder and add the following code.</p>
<p>So we're going to need the open telemetry metrics package for this Kant's.</p>
<p>And we're gonna get the meter provider from it and buy it I mean, the open telemetry metrics package, we are then going to make a new console constant meter.</p>
<p>And we're going to use the meter provider we're gonna make a new meter provider and use get meter, as well as I'm just gonna put your meter name for now, we can change this whenever we want.</p>
<p>Now we can require this file from your application code and use the meter to create and manage metrics.</p>
<p>The simplest of these metrics is a counter.</p>
<p>In this next part, we're going to create an export from our monitoring js file, a middleware function that express can use to count all requests made by route.</p>
<p>So first off, we need to modify IO monitoring j s file.</p>
<p>So once again, I'm just going to copy this sample code from open telemetry open source projects in order to help us count the requests and paste that into my monitoring j s file.</p>
<p>Next, we need to import and use this middleware in our application code.</p>
<p>So our app js file.</p>
<p>So we need to get count all requests from our monitoring js file.</p>
<p>So the module export, we do so by typing const count all requests require monitoring j s.</p>
<p>So literally, we are using this right here.</p>
<p>Now let's get to using it.</p>
<p>Type app use count all requests and call it now when you make requests your service you will meter will count all the requests.</p>
<p>Perfect.</p>
<p>Next up, let's look at initializing and registering a metrics exporter counter metrics are only useful if you can export them somewhere where you can see that.</p>
<p>For this we're going to use Prometheus is creating and registering a metrics exporter is much like the tracing exporter above fast, you need to install the Prometheus exporter by running the following command.</p>
<p>So I'm just going to use npm install and open telemetry exporter permit this next step, we need to add some more code to our monitoring js file.</p>
<p>So once again, I'm going to copy the code given to us by opentelemetry To get started, and paste it into my monitoring js file.</p>
<p>Don't worry, I will share this repo with all of you so that if you do get stuck, you can refer to my finished project.</p>
<p>Now in a separate tab, so just leave this running and show Prometheus is running by running the Prometheus binary from earlier and start your application.</p>
<p>We do so by using the script we wrote.</p>
<p>So NPM start, you should see promethease scrape endpoint and the HTTP localhost 94644 slash metrics, as well as listening for requests on localhost 8080.</p>
<p>Now, each time you browse to localhost 8080, you should see Hello, in your browser and your metrics, and Prometheus should update, you can verify the current metrics by browsing to localhost 9464, forward slash metrics, which should look like this, you should also be able to see the gathered metrics in your Prometheus web UI, we can also add more routes in our app js file.</p>
<p>Let's go ahead and do that to see what that would look like.</p>
<p>So I'm just going to add some pre written code here.</p>
<p>And that is a middle tier route, and another route that has the pot back end.</p>
<p>So now we have our date, homepage from the previous section, our back end route now, and a middle tier route, as well as a new homepage route.</p>
<p>I'm also going to need axios for this.</p>
<p>So another package that will help me in making these requests.</p>
<p>So let's go ahead and import that into my project.</p>
<p>And nice that is done.</p>
<p>Let's run NPM start.</p>
<p>Okay, now let's check everything is working as expected.</p>
<p>The home page now responds with Hello backend.</p>
<p>This is actually because we have two homepage routes.</p>
<p>So I'm just going to get rid of the other one in a bit.</p>
<p>The backend route responds with Hello back end, the date route responds with today's date.</p>
<p>So that looks good.</p>
<p>So I'm just going to delete the initial homepage route that we had that responds with hello world and keep the new one.</p>
<p>Okay, and now let's visit middle tier.</p>
<p>And we get response of Hello backend.</p>
<p>And finally, let's visit matrix where we get a request counter of all the routes we have visited.</p>
<p>Okay.</p>
<p>So this looks like it's all working, we visited all the routes, and I counter seems to be working fine.</p>
<p>Now let's go ahead and see that in the permittees UI.</p>
<p>So we're going to have to pick something to execute.</p>
<p>And there we go.</p>
<p>Now, before we move on to our project, I thought let's take a little bit of time to understand exactly what issues can be detected.</p>
<p>With open telemetry.</p>
<p>Here's just a list that I'm going to go through with you.</p>
<p>Starting with the backend.</p>
<p>In the backend with open telemetry you can pick up bad logic or user input, leading to exceptions being thrown, poorly implemented downstream calls.</p>
<p>So for example to infrastructures like databases or downstream API's, leading to exceptionally long response times.</p>
<p>Or you can pick up poorly performant code on a single API, leading to exceptional response times.</p>
<p>On the front end, with open telemetry, you can detect bad logic or user input leading to JavaScript errors.</p>
<p>You can also use it to find poorly implemented JavaScript, making your UI prohibitively slow, despite performant API's.</p>
<p>And you can even use it to locate geo specific slowness requiring geo distribution.</p>
<p>And finally, for infrastructure, you can use it to identify noisy neighbors running on a host sapping resource from other apps, configuration changes, leading to performance degeneration version audit.</p>
<p>So zero day vulnerability checks, ensuring convict changes went through, or just miss figuration with your DNS making your apps inaccessible.</p>
<p>So that is a list of you thinking of issues that you can detect with open telemetry.</p>
<p>Now that we have that covered, let's move on to our project.</p>
<p>And this part of the course, I want to show you what happens when you are building out an app with a more complicated back end that deals with two services.</p>
<p>It is a hypothetical project that you can adapt to anything that you wish, it is an app that gets movies for your database.</p>
<p>By the end of the project, you will be able to trace exactly how we got the movies, and how long each step took.</p>
<p>Okay, so here is a project I have pre made, thanks to the open source community and inspired by an open telemetry contributor, Alan storm.</p>
<p>It is a project that has two services with one service relying on the other, but not the other way around.</p>
<p>In this project, I have a main dashboard service, as well as the movies service, which will return all the movies for our app.</p>
<p>The layout of this project is similar to what we did in the tracing setup.</p>
<p>However, instead of having a separate tracing js file to trace each service, the code is directly in each file.</p>
<p>So as you can see, each service is in the root of our project.</p>
<p>And just going to minimize this so we can see the code a little better now.</p>
<p>So from the beginning of our course, this should look familiar.</p>
<p>So as a reminder, open telemetry requires that we instantiate a trace provider, configure that trace provider with an exporter and install Open telemetry plugins to instrument specific node modules.</p>
<p>Let's talk through the code.</p>
<p>So we can see here as a refresher, especially as it's organized in a different way than what we saw in the basic implementation.</p>
<p>So first, we are going to get the node trace provider from the open telemetry node package.</p>
<p>A trace provider is what will help us create traces on no Jess.</p>
<p>Next, we will get the console span exporter and the simple span processor from the open telemetry tracing package.</p>
<p>And then we need to get the zipkin exporter from the open telemetry exporter zipkin package.</p>
<p>Now that we have what is necessary, let's move on.</p>
<p>So at the moment, we have made a tracing program.</p>
<p>And to actually generate the spans if you remember, we installed a plugin called Open telemetry plugin dash HTTP, the node a trace provider object is smart enough to notice the presence of a plugin and load it.</p>
<p>This code creates a trace provider and adds a span of processor to it.</p>
<p>The trace processor requires an exporter.</p>
<p>So we instantiate that as well.</p>
<p>Both are responsible for getting the telemetry data out of your service and into another system.</p>
<p>With this code, we create an exporter then use that exporter when creating a span processor, and then added that spam processor to our trace provider.</p>
<p>Okay, so that is what that code does.</p>
<p>Let's actually name our service.</p>
<p>Now, I have left this blank.</p>
<p>So let's go ahead and fill that in.</p>
<p>As this service is going to deal with the main service, I'm just going to call it dashboard service.</p>
<p>Here we're instantiating, a zipkin.</p>
<p>exporter, and then adding it to the trace provider.</p>
<p>We of course need to get Express from the package Express.</p>
<p>And so a server and listen out on port 3000 on one four connections.</p>
<p>The app is currently not going to respond with anything for requests any part as we haven't written anything yet.</p>
<p>I wanted to respond with the dashboard itself and the movies from the movie service.</p>
<p>But before we do that, we need to build out our movies js file.</p>
<p>So this file is exactly the same as the other file just perhaps with some code in different places.</p>
<p>uses a different port.</p>
<p>In this file, I want to deal with the movies.</p>
<p>So I'm just going to rename this service name to movies service.</p>
<p>If I ran this service, we would be listening out to Port 3000.</p>
<p>Now, I'm going to determine how our app responds to a get request to the movies endpoint.</p>
<p>So I am just going to write up, get, and then I'm simply going to put the movies path.</p>
<p>So I'm making this up.</p>
<p>This is an async function, and I'm going to pass through a request and response.</p>
<p>Okay, so there we go.</p>
<p>And then I'm simply going to type rest type Jason as a string.</p>
<p>And response, send Jason stringify.</p>
<p>And I'm just going to send a movie object with, let's say, an array of movies.</p>
<p>So let's put some objects in our array, I'm going to make the array have movie objects.</p>
<p>And each movie object is going to have a name.</p>
<p>So a name like Jaws, a genre.</p>
<p>So for example, jaws is a thriller as a string, and that is my first object.</p>
<p>And then I'm just going to make a quick other object.</p>
<p>This time, let's put a different type of film.</p>
<p>So I'm just going to put the string of Ani, and once again, let's put a genre.</p>
<p>So I'm just making the same movie object just with a different name and genre.</p>
<p>I'm going to put family and make another object.</p>
<p>I'm going to stop after this one, because this is just for illustration purposes.</p>
<p>And let's put Jurassic Park as the name and let's put action as the genre.</p>
<p>Okay, that is it.</p>
<p>That's our array of three movie objects.</p>
<p>Okay, now let's run our app.</p>
<p>So let's actually go to localhost 3000, and put the movies path.</p>
<p>So what I'm doing is I am requesting the URL.</p>
<p>And of course, our app is going to listen out for it and make a trace.</p>
<p>So now let's go over to the zipkin UI and search for recent traces, we will see we recorded a single service trace.</p>
<p>However, if we look through into the trace details, we'll see these traces do not look like the traces we've previously seen.</p>
<p>In our previous examples, one span equaled one service.</p>
<p>However, a span is just a span of time that's related to other spans of time, we can use a span to measure any individual part of our service as well.</p>
<p>The Express auto instrumentation plugin creates spans that measure actions within the Express framework, we can use it to find out how long each middleware took to execute, how long your Express handler took to execute, and so on.</p>
<p>It gives you insights not just into what's going on with the service as a whole, but also individual parts of your Express system.</p>
<p>This is the role most of the contract plugins play in the open telemetry project.</p>
<p>The core plugins are concerned with ensuring each request is bound to a single trace.</p>
<p>But the contract plugins will create spans specific to the behavior of a particular framework.</p>
<p>Okay, great.</p>
<p>Let's carry on.</p>
<p>So now that we've done that, I want to show you how to use open telemetry to instrument a distributed system.</p>
<p>This is what our dashboard js file is for is essentially want my dashboard js file to call the movies service as well.</p>
<p>So let's get to writing that code.</p>
<p>The first thing I am going to do is actually use the node fetch library which we haven't installed yet.</p>
<p>So this service, use the node fetch library to call our movies service.</p>
<p>Let's go ahead and install that.</p>
<p>So I'm just going to get my terminal and type NPM I for install and node batch.</p>
<p>Okay, now, once again, I'm going to have to type apt get, and then use the route of dashboard and then write in async function, so a sick function and pass through a request and response.</p>
<p>Now I am going to write here I need to fetch data from a second service.</p>
<p>And that's the movie service.</p>
<p>I'm just gonna write some pseudocode to remind us of that, fetch data running from second service and My second service is the movies service.</p>
<p>Okay, now, I am going to write a function that will essentially help us get all the URL contact from the movies service.</p>
<p>So essentially our object with the three movies in an array or movie objects in an array.</p>
<p>So let's get to writing this function, I'm going to write this function and pass through two parameters.</p>
<p>So whenever I pass through a URL into this function and a fetch, so the fetch is actually going to use our node fetch library, then I'm going to use these two parameters to essentially get the body of that URL.</p>
<p>So I'm going to use a promise to do this new promise, I'm going to pass through resolve and reject.</p>
<p>And then I'm going to use fetch to fetch the URL.</p>
<p>And then whatever is in the body, I'm going to use so fetch URL, resolve reject, then Russ, Russ text, then body.</p>
<p>So that is my function for getting the URL content.</p>
<p>Let's get to using that.</p>
<p>Okay, I'm just going to actually change this.</p>
<p>I don't like the way this is written.</p>
<p>And I want to make it consistent with the bottom.</p>
<p>So I'm just going to change this up.</p>
<p>So it looks a bit neater is just a different way of writing functions.</p>
<p>So just so it's consistent to that.</p>
<p>Okay.</p>
<p>So once again, let's go down to the code I've pre written.</p>
<p>And in here, I'm going to fetch data running from the second service.</p>
<p>So the movies service, I am going to actually save the contents of the URL as movies.</p>
<p>So const movies, await and use the function that we pre wrote to pass through the URL.</p>
<p>So the URL we want to get the content of is HTTP localhost 3004 slash movies.</p>
<p>So there we go, that is ju L.</p>
<p>It is the same URL that I have written here.</p>
<p>So URL U, r, l, that's what we have done.</p>
<p>And then I'm going to need to require node fetch.</p>
<p>So I'm going to look through right require and the package node fetch, I'm going to put rest type Jason, and rez send Jason stringify.</p>
<p>And now I'm going to write the word dashboard.</p>
<p>Okay, so I'm making an object, and I'm gonna write dashboard, and then whatever we've saved as movies should show up here.</p>
<p>So essentially, the contents of the URL will show up here.</p>
<p>Okay, so now I cannot run this file.</p>
<p>So I could run this file, but we will see an error.</p>
<p>This is because our file relies on the movies service being up and running.</p>
<p>So I'm just going to show you now I'm going to type node dashboard, j.</p>
<p>s.</p>
<p>So it's listening at localhost 3001.</p>
<p>However, if I visit localhost 3001 for slash dashboard, I get an error.</p>
<p>This is because we need our movie service to be running.</p>
<p>So let's go ahead and make that true.</p>
<p>I'm just going to open up a new tab and type node movies j s.</p>
<p>Okay, that is not running and listening at Port localhost 3000.</p>
<p>So now, here's our movies.</p>
<p>And let's refresh or let's rerun the dashboard.</p>
<p>So once again, node dashboard, j s.</p>
<p>And then refresh our page.</p>
<p>Amazing, we will see our dashboard object with the contents of the URL from the Ford slash movies path.</p>
<p>Amazing.</p>
<p>So this is working fine.</p>
<p>Our code is working as it should.</p>
<p>Now, let's see how this looks in our zipkin UI.</p>
<p>So I'm just going to rerun the query and look at our latest.</p>
<p>And there we go.</p>
<p>So once again, to reiterate that, in a nutshell, the dashboard service is dependent on a movie service to populate it.</p>
<p>This is true for many apps you interact with today, and which is why this example is the one I wanted to show you for our project.</p>
<p>Now, we can see here that each span from the services are linked together.</p>
<p>The opentelemetry HTTP plugin took care of this for us, the node fetch plugin use the underlying functionality of node j, s, HTTP and HTTPS to make requests.</p>
<p>So that's how to instrument an application using open telemetry.</p>
<p>Like this is pretty cool, as obviously, you can see our dashboard service, and then you can see exactly what time it's going to the get movies, service, and then coming back.</p>
<p>Okay, that brings us to the end of our project.</p>
<p>I hope you've enjoyed this section.</p>
<p>This is, of course, just the surface of what you can do the opentelemetry.</p>
<p>There is a lot more to it.</p>
<p>But until you get the fundamentals, I sincerely hope you can go through this course again and again until you feel more comfortable building your own projects.</p>
<p>So far, in this project, we have directly gotten data from an app and send the data to zipkin.</p>
<p>But what happens if we want to try sending it to another back end to process our telemetry data? Does that mean we would have to re instrument our whole app? Well, the amazing contributors to open telemetry have come up with a solution to fix this.</p>
<p>The open telemetry collector is a way for developers to receive process and export telemetry data to multiple backends.</p>
<p>It supports open source observability data formats like zipkin, Jaeger permittees, or flume bit, sending it to one or more open source or commercial backends.</p>
<p>In this next section, I'm going to show you how to use it.</p>
<p>Okay, so for this section, and using the open telemetry collector, we're going to be using New Relic as our observability tool of choice.</p>
<p>All I'm going to do is head over to New Relic and sign up.</p>
<p>Next, you'll see some questions, please answer these to the best of your ability.</p>
<p>So for example, where you store your data, and just click save, your account will then be set up.</p>
<p>Once you get to this page right here, I'm just going to ask you to not interact with anything for now, and head over to one dot new relic.com.</p>
<p>Once here, I'm going to ask you to go on the drop down of your profile and click API keys.</p>
<p>Once here, I'm going to ask you to gravitate to creating a new queue and just select ingest license.</p>
<p>I'm going to name this otol example.</p>
<p>And I'm just gonna give it some notes just so we can keep track of our API keys.</p>
<p>And great, our API key is now created.</p>
<p>Let's copy it and move on.</p>
<p>The next thing we're going to do is actually get our open telemetry collector.</p>
<p>For this, I'm going to head over to New Relic GitHub account in which I can get the open telemetry examples.</p>
<p>So I'm just going to ask you to clone this repo into your local machine.</p>
<p>I have already done this.</p>
<p>So I'm just going to go ahead and head over to that repo now.</p>
<p>And here it is.</p>
<p>Once here, I'm going to ask you to navigate to the collectors and our exporter Docker otol config yamo file, because we're gonna have to change this up a little bit.</p>
<p>So please do head over here now.</p>
<p>And I'm just going to ask you to add a little line of code.</p>
<p>This line of code will add zipkin as a receiver, a receiver is aware that data gets into the open telemetry collector.</p>
<p>So because we already have our app configured to use zipkin, we will be telling the open telemetry collector Hey, we will be sending you data in the form of zipkin.</p>
<p>So that is what is happening, we are adding zipkin as a receiver and then giving it an endpoint, which in this case is 0.0 dot 09411.</p>
<p>Now because zipkin report tracing data, we are going to add zipkin as a tracing receiver underneath service.</p>
<p>And that's it.</p>
<p>The next thing we need to do is go over to the Docker compose yamo file, and make sure that the Docker container that runs this open telemetry collector is actually able to receive the data through the same port that it would have if it was zipkin.</p>
<p>So we're going to add the Port 9411, just like so and save it.</p>
<p>Now, according to the readme to run this, we need to use the API key we just created.</p>
<p>So in my terminal, I'm just going To export the New Relic API key I just created with this command.</p>
<p>Next, we need to spin up the Docker container with this command, making sure of course that we are in the correct directory.</p>
<p>So that is my fault.</p>
<p>Let's go into that directory.</p>
<p>So the nr exporter Docker.</p>
<p>And once again, we run the Docker container.</p>
<p>and wonderful.</p>
<p>Now let's go back to our movies dashboard project that we have been working for in this course.</p>
<p>So now I just need to modify our app ever since Thirdly, to work with the open telemetry collector.</p>
<p>For this to work, we need to change two things, we need to change the URL that is reporting at.</p>
<p>So this one right here, I'm simply going to use it like so.</p>
<p>So we need to do is for the dashboard and also for the movies service.</p>
<p>And that's it.</p>
<p>Now, I'm just going to reinstall all the dependencies for those who are just joining us here and I've taken this project from the description below.</p>
<p>And then let's run the two services, like we have been doing previously in this tutorial.</p>
<p>Wonderful.</p>
<p>Okay, now I'm just going to call the services by visiting the dashboard service.</p>
<p>As a reminder, the dashboard service relies on the movies service, I'm going to call it multiple times, so we can get lots and lots of data to work with.</p>
<p>So maybe just a few more.</p>
<p>Okay, done.</p>
<p>Let's move on.</p>
<p>Now that we have our app and have successfully instrumented the open telemetry collector that is forwarding our data to New Relic, we should now be able to visualize our data.</p>
<p>For this, we need to go to the Explorer tab on New Relic.</p>
<p>And once here, we will see the two services, the dashboard service and the movies service, just like in the previous distributed tracing section.</p>
<p>Let's deep dive further.</p>
<p>As you can see in the dashboard service, that was a spike.</p>
<p>Let's find out what was happening.</p>
<p>So it looks like there were 18 traces with nine spans and two entities for the dashboard service.</p>
<p>That sounds right.</p>
<p>Great.</p>
<p>And if we dig deeper, you will see the micro service that our dashboard service was communicating with to actually solve the final result.</p>
<p>Wonderful.</p>
<p>As you can see, we can get a lot of awesome data to do things such as get to the root cause analysis of what could be going wrong in your app, check how your microservices are performing, and so, so much more.</p>
<p>Okay, and there we have it.</p>
<p>That was our open telemetry course, before we finish, I just want to take a moment to recap what we have learned in this course.</p>
<p>So to recap, in this course, we learnt how to set up the back end for a project.</p>
<p>Then we learnt how to implement tracing into our project, as well as metrics if we need to.</p>
<p>And then we also looked at two services and how they communicate.</p>
<p>Thanks to distributed tracing.</p>
<p>I hope you now feel comfortable knowing the benefits of using open telemetry, as well as have a good understanding of how you would go about implementing it into your Node JS projects.</p>
<p>If you are wondering where to go next, with your newfound knowledge, I would suggest learning about infrastructure monitoring and digital experience monitoring.</p>
<p>These are two other ways to visualize, analyze and troubleshoot your entire software stack.</p>
<p>I will leave you with this and a link to New Relic To find out more and get a free account with no expiration date.</p>
<p>Thanks so much again for watching and I'll see you soon   </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Google Search Console – GSC Features and Tools Explained with Examples ]]>
                </title>
                <description>
                    <![CDATA[ By Adam Naor If you are building products, you want to know how people are using the products, how they're hearing about what you are building, and ultimately how they reach you. The Search Console plays an important role in helping you track and mea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-google-search-console/</link>
                <guid isPermaLink="false">66d45d6cc17d4b8ace5b9eb8</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 19 Mar 2021 17:08:49 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/6054d5f5687d62084bf67f9d.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adam Naor</p>
<p>If you are building products, you want to know how people are using the products, how they're hearing about what you are building, and ultimately how they reach you. The Search Console plays an important role in helping you track and measure these operational metrics.</p>
<p>The Console is free to use. You just have to prove to Google that you own a website. Then Google will give you access to this treasure trove of search data.</p>
<p>I am going to walk you through the Google Search Console’s core features and describe each in plain English. I hope this helps you leverage it so you can measure the data points that matter the most to your product.</p>
<h2 id="heading-google-search-console-features-and-core-functionality">Google Search Console: Features and Core Functionality</h2>
<p>The Google Search Console is a web service by Google which allows webmasters to check indexing status and optimize visibility of their websites. Below is a screenshot of the main part of the Search Console so that you can see a visual layout. </p>
<p><img src="https://lh4.googleusercontent.com/VmfGjjHEwTjmyBhv3VVoGSN7GfZaZN9_ZNyF4VvTo0JHZMLzEBBncCStxjjzd0z-CqOquS82rgXDsLj1hVsGqiWKQjNvnviU0Lepm3UQoc-0OTEYSPcC8Xl_DtEHB4eL6xQCBVQD" alt="Image" width="1600" height="135" loading="lazy">
<em>The main tabs on the Google Search Console interface</em></p>
<p>There are five different areas of search performance that the Console enables you to to quickly see and dive deeper into. These 5 areas are:</p>
<ol>
<li>Queries</li>
<li>Pages</li>
<li>Countries</li>
<li>Search Appearance</li>
<li>Dates</li>
</ol>
<p>I want to provide an outline of each. I will then explain how the performance and rendering of your website in each field will tell you a story about your website’s traffic and user experience.</p>
<h3 id="heading-how-to-use-queries-in-google-search-console">How to Use Queries in Google Search Console</h3>
<p>Builders operate at all levels, stay connected to the details, and audit data frequently. Before diving deeper into the Console, a builder will want to know what people are typing into Google.com to reach the landing page or website. </p>
<p>In other words, what are the specific phrases, words, or queries that people are typing in when looking for content pertaining to your page? What is the search intent?</p>
<p>The Console enables builders to see the exact queries that users are entering in order to reach your website. Information pertaining to queries is hugely important as it enables you to see what people are actually typing into their search engine before reaching your page. </p>
<p>Knowing what people are searching for is a great guide for allocating resources or optimizing your pages for what people want to learn about.</p>
<h3 id="heading-how-to-use-pages-in-google-search-console">How to Use Pages in Google Search Console</h3>
<p>Pages is the section of the Console that enables you to see which of your pages are ranking, the number of clicks each page gets, and the total impressions that page has earned. By default, Google lists your most trafficked pages first. </p>
<p>If you don’t know which pages are receiving the most traffic you won’t know how people are finding out about your website. Pages in particular can be revealing as you might think that your website is about topic X but most people are finding out about you by landing on page Y.</p>
<p>When I first built a work from home website, I wanted to build an all purpose site for helping people work from home. </p>
<p>Much to my surprise, the pages that were ranking best, including quad monitor stands and red office chair, struck me as somewhat esoteric. </p>
<p>Nevertheless, that is what people wanted to read about and where they were spending their time. Without the pages section of the Console I could not have gleaned that insight.</p>
<p>You can also use The Console to compare your site’s performance across different devices and operating systems. If you wanted to learn whether or not specific pages are more relevant to users on their mobile or on their desktop, there is data for that. </p>
<p>It would be interesting to discover if you have a lot of users coming from Gmail via their desktop app, for example, and then to see if they spend more time on the page than gmail users who are on their phones.</p>
<h3 id="heading-how-to-use-countries-in-google-search-console">How to Use Countries in Google Search Console</h3>
<p>This section will matter most to people who expect and want to drive traffic from different geographies. If you are an education-based website, for example, you might want users from all over who can access your content. </p>
<p>Where people are coming from can influence the language of the pages you show or help you better interact with your users. If you are a website that sells a physical product, you might value traffic from places you can actually ship to. </p>
<p>The countries tab is useful to confirm your hypothesis that your traffic comes from certain locales. </p>
<h3 id="heading-how-to-use-search-appearance-on-google-search-console">How to Use Search Appearance on Google Search Console</h3>
<p>Some of your traffic will come from standard queries, other sources of traffic will come from video, or Google's "Accelerated Mobile Pages," more commonly known as AMP. The appearance tab captures how Google classifies the appearance of your content. </p>
<p>This tab is the least important in my perspective, because you likely won’t change your behavior as a result of what you see here. </p>
<p>However, if you are practicing agile product development and want to iterate and see how each change impacts search results, this tab will be a helpful guide.</p>
<h3 id="heading-how-to-use-dates-in-google-search-console">How to Use Dates in Google Search Console</h3>
<p>The last tab is the most self explanatory and pertains to time. </p>
<p>You can track your organic search results by day or see trends by zooming out to monthly, quarterly, or annual performance. In general, it is helpful to take a long term perspective on search performance, as anything you do to improve your website will most likely take many days or weeks for Google to index. </p>
<p>Google is looking for websites that are performant, useful to users, fast, responsive, and well structured. If your website affords users these benefits – and drives user engagement over time – your traffic will likely increase and the dates tab will help you see this visually.</p>
<h2 id="heading-conclusion-leverage-the-search-console-to-build-better-products">Conclusion: Leverage the Search Console to Build Better Products</h2>
<p>The Google Search Console is a powerful and necessary tool to review, leverage, and explore core operating metrics for your website. The Console will help you understand how users hear about your site in organic search and which pages they visit on your domain. </p>
<p>By measuring these data points you can improve your website by enhancing individual pages, improving the quality of your search appearance, and seeing how you are improving over time. </p>
<p>Google provides access to the console at no additional cost so that you can build and scale without paying per query.</p>
<p>The console is very powerful and it's a useful tool to leverage when building and deploying any site on the public internet.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google Search Console Explained: What is GSC and How to Use It ]]>
                </title>
                <description>
                    <![CDATA[ By Adam Naor Google Search Console is a web service by Google that lets you see the indexing and performance of your websites and webpages on Google search. At a high level, the search console is a powerful tool to confirm that your website is rankin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/google-search-console-explained/</link>
                <guid isPermaLink="false">66d45d663a8352b6c5a2a9f9</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ metrics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 05 Jan 2021 19:01:25 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5ff3f30c7af2371468bb7980.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adam Naor</p>
<p>Google Search Console is a web service by Google that lets you see the indexing and performance of your websites and webpages on Google search.</p>
<p>At a high level, the search console is a powerful tool to confirm that your website is ranking and that Google can access your website. </p>
<p>You can check and set the crawl rate and view statistics about where your traffic is landing and where you are acquiring traffic from.</p>
<p>The console, like many other web dev tools, is robust and powerful. If you are building your first website you should take time to understand it, play around with it, and learn to leverage it. </p>
<p>This tutorial walks you through the basics of this tool, and can be a useful guide to help you save time when learning which metrics matter for your site’s performance and how you can leverage this data to build better products.</p>
<p>I have lived in the search console for the past six months because I built a website and I care deeply about how people find the content that I write.</p>
<p>Prior to my experience building this site, I was not a regular user of the Search Console. I had to learn about this tool, including what it could do to help me better understand my users and their intent when landing on my website.</p>
<p>I have learned three important lessons about the Search Console’s Performance section and want to pass those lessons on to you.</p>
<h2 id="heading-lesson-1-know-the-source-of-your-traffic-search-vs-discover">Lesson #1: Know the source of your traffic: Search vs Discover</h2>
<p><img src="https://lh3.googleusercontent.com/zMsT6tSzNEUghosvFvS_3MHo0FE0s3GPbI_FnL29FgX-8N1qWgZw5afCRT34mzpvWfIF3owlf_DInR7cnxnxscjGj9pFaIks8F1KSU54s3ZEIkLJrMof-19VBaBmbz8zJseon3ZK" alt="Image" width="554" height="250" loading="lazy"></p>
<p>Google gives you two ways to see how people are reaching your website through Search: via Search results or via Discover.</p>
<p>“Discover” (previously known as Google Feed) is a personalized content feed created by Google that proactively serves relevant content to users. You can’t nominate your content for Discover. If Google thinks that your website is relevant to users, Google will show it to people.</p>
<p>The other type of performance metric, and one that is seemingly far larger, is “Search results”. Search results shows a webmaster four vital pieces of information:</p>
<ol>
<li>Total clicks</li>
<li>Total impressions</li>
<li>Average CTR (Click Thru Rate)</li>
<li>Average Position</li>
</ol>
<p>Discover provides the same information with the exception of Average Position because there are no relative ranking positions within this metric.</p>
<p>When learning to use the Search Console, spend time looking at traffic through the lens of Search and Discover. If you do not see Discover traffic, that means your content has not yet been shown via Discover to users.</p>
<p>When starting a website or blog, you will want users to find your content. Search and discover are the two organic ways that people will do so. Know how many people find you via each.</p>
<h2 id="heading-lesson-2-study-your-average-position">Lesson #2: Study your average position</h2>
<p>When I first started using the Search Console I was amazed (and happy) that I was getting any traffic at all! Over time, your clicks will increase if you are publishing relevant and useful content. </p>
<p>As more people find your website and the site gets more impressions, clicks will go up.</p>
<p>You might be tempted to pat yourself on the back and call it a day. Not so fast!</p>
<p>Each page that you publish on your website is eligible to appear on Google search if you want that page to be crawled and indexed. </p>
<p>Some of your pages will perform very well (that is, they'll land on the first page of Google) and others will land further down (like on the 12th page where nobody will see them).</p>
<p>Over time you will want to monitor and track your average position and find ways to increase your average position by producing higher quality and more relevant content that benefits readers.</p>
<p>Here is a simple strategy to see your average position over time: create articles of similar length, quality, and usefulness to readers. </p>
<p>Then, come back over the ensuing weeks and months and see which ones are starting to rank and what their relative positions are. This strategy is deployed by review sites, thought leadership posts, and even online coding schools.</p>
<p>When I started my first website my average position was around 60. That means that 59 other websites showed up before mine. </p>
<p>Today, that average position is 26.8. Clearly I have a long way to go but it's a step in the right direction. Be aware of this metric and spend time tracking it.</p>
<p><img src="https://lh4.googleusercontent.com/K6rw6C7I7G6D1F5tm9yP7Qu5LHZtdPgmZwv07vW_gfP_3szFEh3SbfhgOTB5E2wQX3JnbIDWy4bRjw3v2h3qJRnHImfP48IaRW9G-j0Boe0P3hohg_dSNCizQrnxP0p8SoZJQcCY" alt="Image" width="909" height="339" loading="lazy">
<em>Source: https://wfhadviser.com/</em></p>
<h2 id="heading-lesson-3-impressions-are-the-top-of-the-funnel">Lesson #3: Impressions are the top of the funnel</h2>
<p>Regardless of the type of website you have - blog, educational, e-commerce, recreational - you will want traffic. </p>
<p>Traffic is just another way of saying unique visitors. Depending on what your website has to offer, you might value certain types of traffic more than others: by region, country, age of users, device operating system, and so on.</p>
<p>But as you focus in on clicks and performance, it all starts with impressions. An impression is counted each time your webpage is shown on a search result page.</p>
<p>In other words, impressions are the top of the funnel. You will need to grow impressions first in order to grow all other metrics.</p>
<p><img src="https://lh6.googleusercontent.com/6K8ZRZ8FiIWGqHYwlCFFMb8auG7lyReNKil79J992RJlyHTpUMsIHR8JQZns6rcK6Y2cebVsubRCZpYIpe5acqK9BIW8Bh6hXm8vdRDNNDdzHE2eJ4-MSou2jUw-I_9H3xqZZa0f" alt="Image" width="906" height="373" loading="lazy"></p>
<p>A word of caution that I have discovered the hard way. If your website is on the lower part of the search results, an impression might count even if the user doesn’t scroll all the way down. </p>
<p>In other words, the way Google counts an impression is seemingly slightly different from how a person might count it. In layperson's terms (that is, not technology) an impression is when you actually see something. </p>
<p>In Google’s terms, an impression is when your website is on a results page and the user sees the results page. In short, scrolling doesn’t seem to impact impression counts.</p>
<h2 id="heading-bringing-it-all-together-know-how-your-users-reach-your-website-to-build-better-products">Bringing It All Together: Know How Your Users Reach Your Website To Build Better Products</h2>
<p>If you want to build a product, you always need to know how your users learned about your product and what they value most. Builders start with the customer and work backwards. </p>
<p>Google’s Search Console is a terrific tool to understand one aspect of the user journey to better align your product, your messaging, and your value-prop with the needs of your clients.</p>
<p>You can use the Performance section of the Search Console to obsess over customers and how they reach you. </p>
<p>Google makes it easy to test this in real time so that your feedback loop is minimal: you can review the crawled page automatically or promagically.</p>
<p><img src="https://lh3.googleusercontent.com/hFhSEp310NkJUuZ09PUzImV9f_eR04Yh6A5JWnNcRiRt_1DW4r6dwQkFGkMSKLPZ5J6ksxmEc3xm2Esi0KxJwEyXmjmsBVPr1TGp1_UjnW6-DzgzCprMwZMBtfVylmWaO0HhqPlU" alt="Image" width="1600" height="792" loading="lazy"></p>
<p>Growing SaaS, a company that notes that SEO is one of the core user acquisition strategies for companies, also convincingly argues that if you don't know where, what, how, or why to measure traffic, you will be missing guidance as to what to build and for whom. </p>
<p>If you build any product - a website, a mobile app, or a tool for Enterprises - you need to know how people hear about your product and reach you.</p>
<p>Imagine if you built a newsletter but had no idea how your email list grew over time or what your subscribers valued most? Sounds crazy, right? That is akin to building a site and not mastering the Search Console.</p>
<p>Certainly this would be a suboptimal situation for any coder or creator.</p>
<p>Builders are never done learning. </p>
<p>The Search Console gives you data and visual guidance on ways to improve your website and customer acquisition. By being curious about new possibilities and acting to explore them, you can do a better job building. </p>
<p>And Google reinforces this by helping guide you along the way. These green circles and checks confirm that the site has live pages and that are properly indexed. It's always a nice plus when the visual design helps the builders :)  </p>
<p><img src="https://lh3.googleusercontent.com/aHwRsAr_vDvLLeV8QXCWqZhKC15ZlgJ82r-xPWCRprJMvxaPzlQxmShrc4nGR-2q93PlyVl3IJKCM5yaeaXDpQkB-bDDSNtclUyfZa5wrHms0GbhXAqRj-ngUb8ll8qE6LaiSx_5" alt="Image" width="1284" height="624" loading="lazy"></p>
<p>Builders not only index on what is going well - and how to improve these trends - but what is not working so that they can course correct. Google’s search console, like other online tools, helps users see broken links and error pages, pages that need improvements, and site speed.</p>
<p>If you were looking at hundreds of pieces of paper in a book - or bulk emails - or thousands of indexed web pages, you need to leverage a tool to understand the data in front of you. </p>
<p>The Search Console is just that.</p>
<p>It is free to use and fast to deploy. It is important to use and critical to master - your product and users will be better served if you leverage it.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Quickly Track PDF Access on a Linux Web Server ]]>
                </title>
                <description>
                    <![CDATA[ Is it possible to track how many times your website's users click to download binary files like PDFs or JPGs? Yes it is possible. Is it easy? I didn't originally think so. I was wrong. The story began while I was optimizing a landing page on my Boots... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/quickly-track-pdf-access-linux-web-server/</link>
                <guid isPermaLink="false">66b9962622379234769e45f1</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ metrics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ pdf ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 02 Dec 2020 17:17:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/12/calculator.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Is it possible to track how many times your website's users click to download binary files like PDFs or JPGs? Yes it is possible. Is it easy? I didn't originally think so. I was wrong.</p>
<p>The story began while I was optimizing a landing page on my <a target="_blank" href="https://bootstrap-it.com/davidclinton/keeping-up">Bootstrap IT website</a> for my new book, <em>Keeping Up: Backgrounders to all the big technology trends you can't afford to miss</em>. </p>
<p>I wanted to provide access to the PDF file of a sample chapter from the book. But I also wanted some way to know how many people actually downloaded it.</p>
<p>Now let's take a step back. <a target="_blank" href="https://analytics.google.com/analytics/web/">Google Analytics</a> is a free service that uses code snippets inserted into your HTML files to collect and display data on how often your files were accessed. </p>
<p>The magic - and problem - of Google Analytics is in just how much information about your users can be revealed. I discussed some of the privacy concerns involved with the service in the Keeping Up book. I also mentioned how I feel at least a bit guilty for using the service myself on my own sites.</p>
<p>At any rate, all by itself, Google Analytics isn't able to tell you much about how your web-based PDFs are being used. Of course, there are tricks for getting around the problem. </p>
<p>Traditional approaches include setting up the <a target="_blank" href="https://marketingplatform.google.com/about/tag-manager/">Google Tag Manager</a>, customizing the syntax of the request URLs you use or, if your site uses WordPress software, working with the <a target="_blank" href="https://www.monsterinsights.com/">Monster Insights plugin</a>. Each of those can work, but will require a fairly steep learning curve.</p>
<p>But I'm a Linux sysadmin. And, as I never fail to remind the people around me, the best sysadmins are lazy. Learning curve? That sounds suspiciously like work. Not gonna happen on my watch.</p>
<p>So here's the deal. My web server, obviously, runs Linux. And, under the hood, HTTP traffic is handled by Apache. That means that everything happening to and on my websites is going to be logged by Apache. </p>
<p>Everything. All it'll take to give me what I need to know about what my PDF sample chapter has been up to, is a single line of Bash run from my local workstation:</p>
<pre><code>echo <span class="hljs-string">"cd /var/log/apache2 &amp;&amp; grep -nr KeepingUpSampleChapter"</span> \
   | ssh -i PrivateKey.pem LoginName@bootstrap-it.com
</code></pre><p>Let's break that down. The first of the two commands in quotation marks (<code>cd /var/log/apache2</code>) will move us to the /var/log/apache2/ directory on the Linux server where Apache writes its logs. That's not rocket science.</p>
<p>There are going to be multiple files of interest in that directory. That's because messages relevant to regular access and errors are saved to different files, and because file rotation policies mean that there could be more than one version of either of those files, too. So I'll use <code>grep</code> to search all the uncompressed files for the <code>KeepingUpSampleChapter</code> string. <code>KeepingUpSampleChapter</code> is, of course, part of the filename of the PDF.</p>
<p>I then pipe that command to SSH, which will connect to my remote server and execute the command. Here's what a single entry would look like from a successful run (I've removed the requester's IP address out of privacy concerns):</p>
<pre><code>other_vhosts_access.log<span class="hljs-number">.1</span>:<span class="hljs-number">12200</span>:bootstrap-it.com:<span class="hljs-number">443</span> &lt;requester<span class="hljs-string">'s IP Address&gt; - - [01/Dec/2020:16:39:36 -0500] "GET /davidclinton/KeepingUpSampleChapter.pdf?pdf=SamplePDF HTTP/1.1" 200 65146 "https://bootstrap-it.com/davidclinton/keeping-up/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"</span>
</code></pre><p>We can see:</p>
<ul>
<li>The log file where the entry appeared (<code>other_vhosts_access.log.1</code>)</li>
<li>The requester's IP address (redacted)</li>
<li>The timestamp telling us exactly when the file was accessed</li>
<li>The relative location of the file on the server file system (<code>/davidclinton/KeepingUpSampleChapter.pdf</code>)</li>
<li>The URL from which the request was made (<code>https://bootstrap-it.com/davidclinton/keeping-up/</code>)</li>
<li>And the browser the user was running</li>
</ul>
<p>That's a lot of information. If we're just curious about how many <em>times</em> the file was downloaded, we can simply pipe the output to the <code>wc</code> command that will tell us three things about the output: the number of lines, words, and characters it contained. That command would look like this:</p>
<pre><code>echo <span class="hljs-string">"cd /var/log/apache2 &amp;&amp; grep -nr KeepingUpSampleChapter | wc"</span> \
   | ssh -i PrivateKey.pem LoginName@bootstrap-it.com
</code></pre><p>There is one possible limitation with this method. If your website is busy, the log files will roll over frequently, often more than once a day. By default, after the first rollover, the files are compressed using the <code>gz</code> algorithm, which can't be read by <code>grep</code>.</p>
<p>The <code>zgrep</code> command won't have any trouble handling such files, but the process could end up taking a very long time. You might consider writing a simple custom script to decompress each <code>gz</code> file and then run regular <code>grep</code> against its contents. That'll be your project.</p>
<p><em>There's much more administration goodness in the form of books, courses, and articles available at my <a target="_blank" href="https://bootstrap-it.com/davidclinton">bootstrap-it.com</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 3 Privacy-Focused Open Source Google Analytics Alternatives for Your Next Project ]]>
                </title>
                <description>
                    <![CDATA[ By Leonardo Faria As a content creator, I like to know the page analytics of my website.  Overall, I am curious to know how many people are reading my content, where they came from (referrer and countries), and what the most popular pages are. 20 yea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/3-privacy-focused-open-source-google-analytics-alternatives-for-your-next-project/</link>
                <guid isPermaLink="false">66d8516c29e30bc0ad477590</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 04 Sep 2020 12:20:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/09/markus-winkler-IrRbSND5EUc-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Leonardo Faria</p>
<p>As a content creator, I like to know the page analytics of my website. </p>
<p>Overall, I am curious to know how many people are reading my content, where they came from (referrer and countries), and what the most popular pages are.</p>
<p>20 years ago, tools like <a target="_blank" href="http://www.webalizer.org/">Webalizer</a> were all that we could count on. Tools like this parsed Apache logs and created static pages with the processed data.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/webalizer.jpg" alt="webalizer screenshot" width="600" height="400" loading="lazy"></p>
<p>Another way to get page analytics was to insert an image - often invisible - on your site. By using the request headers sent to the server, people could count visitors and get a little bit more information such as origin IP, browser, and operating system. This technique is old, but services like <a target="_blank" href="https://statcounter.com/">statcounter</a> still provide this functionality.</p>
<p>In 2005 Google launched Google Analytics after acquiring <a target="_blank" href="https://en.wikipedia.org/wiki/Urchin_(software)">Urchin</a>, a company which also analyzed server logs. Its presence has been growing since the early days and it has far more usage than any of its competitors. But, there are a few reasons <a target="_blank" href="https://plausible.io/blog/remove-google-analytics">why you should stop using Google Analytics on your website</a>: </p>
<p>1) It is owned by Google, which uses analytics for their own benefit
2) It affects site speed by adding 45KB to page requests
3) It is too invasive, collecting lots of personal data that you don't need
4) It is blocked by many plugins and browsers, creating inaccurate data</p>
<p>With all this in mind, I want to share a few open source alternatives I have been looking at for the last few months.</p>
<h2 id="heading-fathom">Fathom</h2>
<p><a target="_blank" href="https://usefathom.com/">Fathom</a> (<a target="_blank" href="https://app.usefathom.com/share/sqqvo/chimp+essentials">demo</a>) is a light Golang app to collect analytics. </p>
<p>They have different paid plans which start at $14/month. They also have a lite version that you can install on your server or Heroku for free.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/fathom.jpg" alt="Fathom screenshot" width="600" height="400" loading="lazy"></p>
<p>The lite version uses cookies and it gives you information about unique visitors, page views, average time on site, bounce rate, top pages, and top referrers. Fathom stores data in SQLite, MySQL, or Postgresql databases.</p>
<h2 id="heading-umami">umami</h2>
<p><a target="_blank" href="https://umami.is/">umami</a> (<a target="_blank" href="https://app.umami.is/share/ISgW2qz8/flightphp.com">demo</a>) is a solution created with Next.js, making it very easy to deploy. In my case, used Vercel.</p>
<p>On top of unique visitors, page views, average time on site, bounce rate, top pages, and top referrers, umami also shows you information about countries, browsers, OS and device data.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/umami.jpg" alt="umami screenshot" width="600" height="400" loading="lazy"></p>
<h2 id="heading-plausible">Plausible</h2>
<p>I think I first heard about <a target="_blank" href="https://plausible.io/">Plausible</a> (<a target="_blank" href="https://plausible.io/plausible.io">demo</a>) in the "<a target="_blank" href="https://changelog.com/podcast/396">De-Google-ing your website analytics</a>" Changelog podcast. From a product perspective, it is nice to see a <a target="_blank" href="https://plausible.io/roadmap">public roadmap</a> out in the wild so customers can learn what is coming next.</p>
<p>Their plans start at $6/month and go up according to your page views - like Fathom. They also have an <em>alpha</em> self-hosted option, but I didn't have a chance to test it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/plausible.jpg" alt="plausible" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>There are alternatives out there, and you don't need to worry about a big corp looking at you or your users with these options. Each service's setup time is very similar, and once you're done, you can add multiple sites just like you would with Google Analytics.</p>
<p>I don't have a favorite. Feature-wise, umami provides all the basic information you would want to know for free. It's also very easy to set up on services like Vercel or Netlify. </p>
<p>Both Fathom and Plausible offer free trials so you can easily test their solutions before deciding.</p>
<p><em>Do you know another minimalist, open source alternative to Google Analytics? Let me know in the <a target="_blank" href="https://leonardofaria.net/2020/09/01/three-privacy-focused-open-source-google-analytics-alternatives/">comments</a> section of my blog.</em></p>
<p>If you liked this article, follow me on <a target="_blank" href="https://twitter.com/leozera">Twitter</a> and <a target="_blank" href="https://github.com/leonardofaria">GitHub</a>. </p>
<p>Cover photo by <a target="_blank" href="https://unsplash.com/photos/IrRbSND5EUc">Markus Winkler/Unsplash</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Track and Analyze Web Vitals to Improve SEO ]]>
                </title>
                <description>
                    <![CDATA[ By Adam Henson Good news - we now have a brand new set of standards by which to judge our search engine's worthiness! ?  If you're like me, you may not have been jumping for joy when you read Google's announcement of its upcoming search algorithm cha... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-track-and-analyze-web-vitals-to-improve-seo/</link>
                <guid isPermaLink="false">66d45d5fbd438296f45cd385</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SEO ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web vitals ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 19 Jun 2020 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/vitals.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adam Henson</p>
<p>Good news - we now have a brand new set of standards by which to judge our search engine's worthiness! ? </p>
<p>If you're like me, you may not have been jumping for joy when you read <a target="_blank" href="https://webmasters.googleblog.com/2020/05/evaluating-page-experience.html">Google's announcement of its upcoming search algorithm change</a>. But after taking some time to breathe, I believe it's a positive change. </p>
<p>The announcement emphasizes web page <em>experience</em> and its role in the future of search indexing. By following this new direction, we can not only provide a better experience to website users, but also establish effective strategies to improve SEO.</p>
<h2 id="heading-what-are-web-vitals">What are Web Vitals?</h2>
<p>The following metrics encompass Web Vitals as defined at the time of this writing.</p>
<ul>
<li><a target="_blank" href="https://web.dev/fcp/">First Contentful Paint (FCP</a>) measures the time from when the page starts loading to when any part of the page's content is rendered on the screen.</li>
<li><a target="_blank" href="https://web.dev/fid/">First Input Delay (FID)</a> measures the time from when a user first interacts with a page to the time when the browser is able to respond to that interaction.</li>
<li><a target="_blank" href="https://web.dev/lcp/">Largest Contentful Paint (LCP)</a> metric reports the render time of the largest content element visible within the viewport.</li>
<li><a target="_blank" href="https://web.dev/time-to-first-byte/">Time to First Byte (TTFB)</a> is the time that it takes for a user's browser to receive the first byte of page content.</li>
<li><a target="_blank" href="https://web.dev/cls/">Cumulative Layout Shift (CLS)</a> measures the sum total of all individual <em>layout shift scores</em> for every <em>unexpected layout shift</em> that occurs during the entire lifespan of a page. To calculate the <em>layout shift score</em>, the browser looks at the viewport size and the movement of unstable elements in the viewport between two rendered frames.</li>
</ul>
<h2 id="heading-why-are-web-vitals-important">Why are Web Vitals Important?</h2>
<p>In recent years, <a target="_blank" href="https://developers.google.com/web/tools/lighthouse">Lighthouse</a>, an open-source automated tool for improving the quality of web pages, became widely adopted as an industry standard. </p>
<p>Now another Google project called <a target="_blank" href="https://github.com/GoogleChrome/web-vitals">Web Vitals</a> has emerged, deriving metrics from <strong>real users</strong> in a way that accurately matches how they're measured by Chrome and reported to other Google tools. </p>
<p>With it, we can establish page experience perspective from an SEO point of view, analyze, and adjust accordingly. ?</p>
<blockquote>
<p>Core Web Vitals are the subset of Web Vitals that apply to all web pages, should be measured by all site owners, and will be surfaced across all Google tools. Each of the Core Web Vitals represents a distinct facet of the user experience, is measurable <a target="_blank" href="https://web.dev/user-centric-performance-metrics/#how-metrics-are-measured">in the field</a>, and reflects the real-world experience of a critical <a target="_blank" href="https://web.dev/user-centric-performance-metrics/#how-metrics-are-measured">user-centric</a> outcome.</p>
</blockquote>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://web.dev/vitals/">https://web.dev/vitals/</a></div>
<h2 id="heading-web-vitals-in-google-search-console">Web Vitals in Google Search Console</h2>
<p>Search Console provides reporting of how real users are accessing a website and a variety of data about these users. </p>
<p>Core Web Vitals are reported as a summary showing the total number of URLs that are good, need improvement, or are just poor. ?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screen-Shot-2020-06-17-at-11.30.00-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Google Search Console Core Web Vitals</em></p>
<h2 id="heading-sending-web-vitals-to-google-analytics-and-visualizing-in-data-studio">Sending Web Vitals to Google Analytics and Visualizing in Data Studio</h2>
<p>Search Console provides a summary of results in the grand scheme, but in order to get detailed reporting we can take this a step further. The <a target="_blank" href="https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics">Web Vitals GitHub project documents a way of capturing metrics as analytics events</a> that can be visualized as charts in Google's Data Studio.</p>
<p>Disclaimer: I haven't personally been able to wire analytics Web Vitals events to Data Studio, and the documentation is lacking at this time. But I'll update this post once I can put together an example.</p>
<h2 id="heading-visualizing-and-analyzing-web-vitals-in-real-time-with-automated-lighthouse-check">Visualizing and Analyzing Web Vitals in Real Time with Automated Lighthouse Check</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/web-vitals-screenshot-2000.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.automated-lighthouse-check.com/dashboard/demo/web-vitals">Automated Lighthouse Check Web Vitals Demo</a></em></p>
<p>Google Analytics and Data Studio are powerful tools that provide great insight. And best of all, they are free! </p>
<p>Automated Lighthouse Check is a website that monitors websites with Lighthouse and now offers a Web Vitals implementation. You can embed a JS snippet on your website and start collecting Web Vitals metrics in real time. </p>
<p>One advantage of this tool is its simple setup process and easy filtering. You can <a target="_blank" href="https://www.foo.software/web-vitals">filter data by URL as well as browser, OS, and device</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The road to SEO success is a winding one, but fortunately we now have a more concrete set of guidelines. If your goal is to achieve high ranking on Google's search engine, it's a good idea to utilize the tools and projects Google recommends including Lighthouse and Web Vitals.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to set up and track YouTube Channel performance with Google Analytics ]]>
                </title>
                <description>
                    <![CDATA[ Managing a YouTube channel is a lot of work. It includes content experimentation which can make or break your SEO effectiveness for your channel. How can we track our channel’s performance to see what works? Why is SEO important? How is SEO importan... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-and-track-youtube-channel-performance-with-google-analytics/</link>
                <guid isPermaLink="false">66b8e36893a17625e9eef10f</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #content marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Wed, 18 Mar 2020 13:27:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/youtube-analytics-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Managing a YouTube channel is a lot of work. It includes content experimentation which can make or break your SEO effectiveness for your channel. How can we track our channel’s performance to see what works?</p>
<ul>
<li><a class="post-section-overview" href="#heading-why-is-seo-important">Why is SEO important?</a></li>
<li><a class="post-section-overview" href="#heading-how-is-seo-important-to-youtube">How is SEO important to YouTube?</a></li>
<li><a class="post-section-overview" href="#heading-and-what-is-google-analytics">And what is Google Analytics?</a></li>
<li><a class="post-section-overview" href="#heading-how-do-i-connect-my-channel">How do I connect my channel?</a></li>
<li><a class="post-section-overview" href="#heading-what-will-i-be-able-to-see">What will I be able to see?</a></li>
<li><a class="post-section-overview" href="#heading-what-wont-i-be-able-to-see">What won’t I be able to see?</a></li>
<li><a class="post-section-overview" href="#heading-what-else-can-i-do-with-youtube-and-google-analytics">What else can I do with YouTube and Google Analytics?</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/P8wv4ylc_-s" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-why-is-seo-important">Why is SEO important?</h2>
<p><a target="_blank" href="https://moz.com/learn/seo/what-is-seo">SEO, or Search Engine Optimization</a>, is the practice of writing and organizing content in a way that search engines like Google can crawl and ultimately understand what your website or YouTube channel is about.</p>
<p>Using this information, Google and others make decisions with their algorithms to determine which content is of higher quality, more relevant, and more likely to answer the question you’re looking for on their search engine in the first place. With that information, the search engines rank this content and display their results ordered by those rankings.</p>
<h2 id="heading-how-is-seo-important-to-youtube">How is SEO important to YouTube?</h2>
<p>Just like any other website, YouTube gets crawled by Google and other search engines. Additionally, YouTube has its own internal search that will take these same things into consideration when deciding how to display results on a YouTube search.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/searching-for-code-channels-on-youtube.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Searching for "code" channels on YouTube</em></p>
<p>This means, depending on how well you create your descriptions, manage your keywords, or name your videos, it could impact how well your videos rank in the results. And this can impact how many views your videos get.</p>
<p>This also applies to your channel. You have opportunities to experiment with effectiveness through the content you feature, your channel description, and the name of your channel.</p>
<h2 id="heading-and-what-is-google-analytics">And what is Google Analytics?</h2>
<p>Google Analytics is a <a target="_blank" href="https://analytics.google.com/analytics/web/">free analytics tool</a> from Google that will allow you to gain better insights into your traffic. I previously wrote about <a target="_blank" href="https://www.freecodecamp.org/news/making-sense-of-google-analytics-and-the-traffic-to-your-website/">what is Google Analytics and how you can make sense of it</a> which provides a more in depth view. So if you want to learn a little more before diving in, I highly recommend starting there.</p>
<h2 id="heading-how-do-i-connect-my-channel">How do I connect my channel?</h2>
<h3 id="heading-setting-up-a-new-tracking-code">Setting up a new tracking code</h3>
<p>To start, we’ll need a tracking code from Google Analytics. Google has some great up to date resources on how to do this, so I'm not going to try to re-explain here:</p>
<ul>
<li><a target="_blank" href="https://support.google.com/analytics/answer/1042508">Setting up a new property</a></li>
<li><a target="_blank" href="https://support.google.com/analytics/answer/1008080?hl=en">Getting your Tracking ID</a></li>
</ul>
<p>Though some say you can use your website’s property and create a filtered View, I recommend starting with a separate property. That way you don’t have to worry about any data crossover or setting up complicated filters.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-tracking-id.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Tracking ID in Google Analytics</em></p>
<p>Your tracking ID will be in the following format: <code>UA-######-#</code>. Once you have that, we're ready to go.</p>
<h3 id="heading-adding-your-tracking-code-to-youtube">Adding your tracking code to YouTube</h3>
<p>There are a few steps we have to navigate through to find where we can set up our Google Analytics account. If you want to skip to the right place, you can visit <a target="_blank" href="https://www.youtube.com/advanced_settings">youtube.com/advanced_settings</a>.</p>
<p>To take the long route, which will also help you get a little more familiar with your YouTube account, first head over to the <strong>Settings</strong> section from within your <strong>YouTube Studio</strong> page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/youtube-studio-channel-settings.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Finding Settings on your YouTube Studio dashboard</em></p>
<p>Once selected, find the <strong>Advanced channel settings</strong> link by visiting <strong>Channel</strong>, <strong>Advanced Settings</strong>, and then scrolling down to the bottom.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/youtube-advanced-channel-settings.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><strong>Advanced channel settings</strong> on YouTube</em></p>
<p>Finally, scroll down to the bottom of the page again, find the <strong>Google Analytics property tracking ID</strong> field, enter the tracking ID you created, and hit save.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/youtube-advanced-channel-settings-google-analytics-property-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Setting the Google Analytics property tracking ID for your YouTube channel</em></p>
<h3 id="heading-sit-back-and-wait">Sit back and wait</h3>
<p>Google Analytics will only show your website traffic from the point it was set up and through the future. Unfortunately we can’t check out that weekend your video first went viral if you didn’t have Google Analytics set up then, but at least we’re prepared for the next time!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/friends-recline-chair.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Joey and Chandler reclining their chairs</em></p>
<p>That said, now's the time to continue working hard on your channel since you have the ability to track how that hard work is paying off as people visit your channel.</p>
<h3 id="heading-optional-setting-up-site-search">Optional: Setting up Site Search</h3>
<p>Setting up <a target="_blank" href="https://support.google.com/analytics/answer/1012264?hl=en">Google Analytic’s Site Search</a> feature gives us an easy way to separate out search usage to make it easier to gain insight into how people are searching our channel.</p>
<p>To enable Site Search, we want to go to the <strong>Admin</strong> section of our Google Analytics property and then navigate over to <strong>View Settings</strong>. Once there, under the <strong>Site Search</strong> settings at the bottom, first click the button to toggle on <strong>Site search Tracking</strong>, then type “query” into the <strong>Query parameter</strong> input.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-site-search-tracking.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><strong>Site search Tracking</strong> in Google Analytics</em></p>
<p>Optionally, though recommended, you can select to strip query parameters out of your URL. This means that in your main content view, you will see all traffic as /search instead of many instances of /search?query=[keyword], which can be more cumbersome to analyze.</p>
<p><em>Note: before you set this up, it’s <a target="_blank" href="https://www.e-nor.com/blog/google-analytics/best-practices-views-google-analytics">generally recommended to have more than one view for your property</a>. I would recommend having at least 2 views, a Raw Data view and Main view. You would only apply the Site Search feature to your Main view. This will help to make sure you can always see the unfiltered Raw Data view if you want.</em></p>
<h2 id="heading-what-will-i-be-able-to-see">What will I be able to see?</h2>
<h3 id="heading-how-many-people-visited-my-channel">How many people visited my channel?</h3>
<p>The first thing we get immediately with our new data when we open up our Google Analytics property is how many people visited our site.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-home.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Analytics Home</em></p>
<p>The default here is in the past 7 days, but you can change the time range in the bottom left corner of the panel.</p>
<p>What this also provides is a quick insight into how the number of people has changed since the previous period (the 7 days before in this example). As we can see here, the number of people this week has increased by 13.9% which is awesome news for freeCodeCamp’s YouTube channel, proving whatever they did is working.</p>
<h3 id="heading-how-are-people-finding-our-channel">How are people finding our channel?</h3>
<p>So how do we figure out if the strategies we’re using (like SEO) to get people to our channel are effective? By analyzing our organic search traffic.</p>
<p>By navigating to the <strong>Source/Medium</strong> report by visiting <strong>Acquisition</strong>, <strong>All Traffic</strong>, then <strong>Source/Medium</strong>, we can see what sources are providing our YouTube channel the most traffic.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-source-medium-report.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Source/Medium report in Google Analytics</em></p>
<p>By clicking in to <strong>google / organic</strong>, we can also see how this has changed over time.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-organic-google-referral-report.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Organic Google traffic report in Google Analytics</em></p>
<p>While analyzing a single week isn’t the most effective, being able to tell how your organic traffic has changed over multiple weeks will be able to tell you if your strategy is working.</p>
<h3 id="heading-what-websites-and-pages-are-people-coming-from">What websites and pages are people coming from?</h3>
<p>Navigating to the <strong>Referrals</strong> report by going to <strong>Acquisition</strong>, <strong>All Traffic</strong>, and then <strong>Referrals</strong>, we can see that most of the referral traffic for the <a target="_blank" href="https://www.youtube.com/channel/UC8butISFwT-Wl7EV0hUK0BQ">freeCodeCamp YouTube</a> is from <a target="_blank" href="https://www.freecodecamp.org/">freeCodeCamp.org</a> itself.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-freecodecamp.org-referral-traffic.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Referral traffic showing freecodecamp.org as highest referrer in Google Analytics</em></p>
<p>But say we want to see what pages those referrals are coming from. We can find this out by clicking on the <strong>freecodecamp.org</strong> link in the view above where we can see a full breakdown of which pages are giving the channel the most traffic.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-referring-pages-from-freecodecamp.org.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>freecodecamp.org referral pages on Google Analytics</em></p>
<h3 id="heading-what-are-people-searching-for-on-my-channel">What are people searching for on my channel?</h3>
<p>After setting up <a target="_blank" href="https://support.google.com/analytics/answer/1012264?hl=en">Site Search</a> on your Google Analytics account, you’ll be able to get better insight into how people are actually searching your site.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-search-terms.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Search Terms report in Google Analytics</em></p>
<p>Here we can see what keywords people want to see the most, meaning we can tailor our content and future videos to those keywords, making our channel more effective.</p>
<h3 id="heading-more-insights">More insights</h3>
<p>By default, you’ll get a lot of other cool insights from Google Analytics that are baked in like where your visitors are physically located and whether they’re visiting on a desktop or mobile device.</p>
<p>To learn more about what you can see, check out <a target="_blank" href="https://www.freecodecamp.org/news/making-sense-of-google-analytics-and-the-traffic-to-your-website/">my article on making sense of Google Analytics</a>.</p>
<h2 id="heading-what-wont-i-be-able-to-see">What won’t I be able to see?</h2>
<p>While the information you’ll discover through Google Analytics is important, it’s not all inclusive. There are many points you’ll need to dive into YouTube’s own Analytics tool to see.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/youtube-studio-analytics-dashboard.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Analytics dashboard in YouTube Studio</em></p>
<h3 id="heading-video-analytics">Video analytics</h3>
<p>Video states and actions aren’t going to be visible in Google Analytics, which includes things like Play, Pause, and time watched.</p>
<p>However, by using the <strong>Engagement</strong> tab in the <a target="_blank" href="https://studio.youtube.com/">YouTube Studio</a> <strong>Analytics</strong> section, we can see how long people are watching our videos and a graph of the <strong>Audience retention.</strong> This will help us determine how the content of our videos is performing.</p>
<h3 id="heading-subscribers">Subscribers</h3>
<p>You’re not going to be able to gain insights into how the visitors on your channel are subscribing.</p>
<p>The good news is you can find this by visiting the the <strong>Analytics</strong> section in your YouTube Studio page, then clicking the <strong>Audience</strong> tab at the top.</p>
<h3 id="heading-dig-in-to-youtube-studio-analytics">Dig in to YouTube Studio Analytics</h3>
<p>There’s a whole lot you can find out if you dig around YouTube Studio Analytics. Take the time to poke around both Analytics report solutions and learn what information is most useful to providing an impactful experience for your channel.</p>
<h2 id="heading-what-else-can-i-do-with-youtube-and-google-analytics">What else can I do with YouTube and Google Analytics?</h2>
<h3 id="heading-track-links-from-youtube-to-your-website">Track links from YouTube to your website</h3>
<p>If you have a website outside of your YouTube channel and have Google Analytics set up on it, you can build custom URLs that will allow you to see your YouTube traffic as a campaign. This is useful not only for YouTube, but any other source you’re directing traffic to your website from.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/google-analytics-campaign-url-builder.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Building campaign URLs <a target="_blank" href="https://ga-dev-tools.appspot.com/campaign-url-builder/">Campaign URL Builder</a></em></p>
<p>Google Analytics provides this capability using URL parameters attached to the links. You can learn more about the setup and what you need to do with <a target="_blank" href="https://support.google.com/analytics/answer/1033863?hl=en">Google’s Analytics Help site</a>.</p>
<p>It should also be noted that you don’t really need to set up your YouTube channel with Google Analytics to make use of this feature.</p>
<h3 id="heading-track-how-videos-are-watched-when-embedded-on-your-website">Track how videos are watched when embedded on your website</h3>
<p>YouTube provides an <a target="_blank" href="https://developers.google.com/youtube/iframe_api_reference">API</a> that developers can use to write custom JavaScript and track usage of embedded videos on a given website.</p>
<p>Using this, we can send custom events based on time references or video actions (like play and pause) to get a better idea of how the videos on our site are being used.</p>
<p>To be clear – this is only for videos embedded on your website and will probably track usage with your website's Google Analytics property unless you configure it otherwise.</p>
<p>Check out <a target="_blank" href="https://developers.google.com/youtube/iframe_api_reference">YouTube iFrame Player API</a> for more info.</p>
<h3 id="heading-pretty-much-anything-google-analytics-provides-by-default">Pretty much anything Google Analytics provides by default</h3>
<p><a target="_blank" href="https://www.freecodecamp.org/news/making-sense-of-google-analytics-and-the-traffic-to-your-website/">There’s a whole lot you can do with Google Analytics</a>, whether it’s getting better visibility into where people are coming from or where they’re physically located. And by connecting your YouTube channel you automatically get those insights.</p>
<h2 id="heading-the-more-resources-the-more-insight-you-can-gain">The more resources, the more insight you can gain</h2>
<p>Though there are benefits to both YouTube Analytics and Google Analytics, having more information will ultimately help you make better judgement calls about how you manage your channel and content. Use these tools to help launch yourself to inevitable YouTube stardom!</p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to use Google Tag Manager to maintain Google Analytics and other marketing tags ]]>
                </title>
                <description>
                    <![CDATA[ Managing code snippets and pixels on your website or app to measure traffic can be a little bit stressful, especially if you have a marketing team that constantly needs to make changes. Luckily, there are tools out there like Google Tag Manager that ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-google-tag-manager-to-maintain-google-analytics-and-other-marketing-tags/</link>
                <guid isPermaLink="false">66b8e377c9bc6d235bb126b0</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #content marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Digital Marketing  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google tag manager ]]>
                    </category>
                
                    <category>
                        <![CDATA[ marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #reporting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SEO ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Wed, 20 Nov 2019 16:04:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/take-control-of-your-marketing-tags.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Managing code snippets and pixels on your website or app to measure traffic can be a little bit stressful, especially if you have a marketing team that constantly needs to make changes. Luckily, there are tools out there like Google Tag Manager that will make them a little easier to wrangle.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/giphy.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Sandy wrangling</em></p>
<h2 id="heading-what-is-google-tag-manager"><strong>What is Google Tag Manager?</strong></h2>
<p>If you’ve ever worked with any kind of analytics software, or you have worked with a marketing team before, you’ve probably heard the word pixel thrown around. A pixel is literally what it sounds like: a 1x1 image that sends information to a server through an image request.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-analytics-pixel-request.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Analytics pixel request</em></p>
<p>Though pixels are still common, many teams have moved towards small javascript snippets that sit right along side the rest of your HTML. They will allow software like Google Analytics to run their own scripts on your page, sometimes even with a pixel backup, in the event that a browser doesn't run JavaScript.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/crazy-egg-tracking-snippet.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Crazy Egg snippet</em></p>
<p>These pixels and snippets work great. But when you’re dealing with a bunch of them and they all use the same data, it might seem like you’re just adding to an unmanageable mess of single use code snippets that never feel like they’re in the right place.</p>
<p>Google Tag Manager, or GTM, is a software solution to manage these pixels and snippets for you. To start, GTM works pretty much like any of those other code snippets, as it’s a code snippet itself. But where it shines is that you get to manage the rest of those pixels and snippets along with the flow of data inside GTM, leaving it to be the only snippet to manage within your code.</p>
<h2 id="heading-why-do-i-want-to-use-it"><strong>Why do I want to use it?</strong></h2>
<h3 id="heading-fewer-code-changes-fewer-deploys"><strong>Fewer code changes, Fewer deploys</strong></h3>
<p>Most of the time, if you’re managing these snippets in your code, each change will require another merge request and another deploy to get the changes out. Not only does this add more risk, as you need to make yet another change to the code, but this is additional time spent dealing with your deploy pipeline and making sure everything is working as it should be. </p>
<p>GTM allows you to break outside of that flow, giving you more flexibility to get changes out that could give some needed insight into fixing some UI errors or could add a few bucks to the bottom line.</p>
<h3 id="heading-more-manageable-data-flow"><strong>More manageable data flow</strong></h3>
<p>Wrangling all the different variables throughout your application, making sure they’re all available in the right spot, and keeping up with avoiding breaking any changes can prove to be challenging. This also makes your code more fragile and prone to breaking. </p>
<p>Google Tag Manager utilizes what they call a <code>dataLayer</code>, which essentially functions like an array of events that it listens to. This allows you to push or seed new data to make available within GTM itself. And it means you’re funneling all of your variables to one spot in the code. This lets whoever manages GTM do the rest – they can use that data with peace of mind, knowing that your data flow won’t break after forgetting to update 1 out of 10 spots.</p>
<h3 id="heading-ability-to-give-marketers-a-little-more-access"><strong>Ability to give marketers a little more access</strong></h3>
<p>This is an opportunity to free up some of your time by letting the marketing team deal with tag changes themselves rather than you being the middle man for them. Perhaps they need to adjust the ID for your analytics software or maybe they want to add <a target="_blank" href="https://www.crazyegg.com/">Crazy Egg</a>. With the right permissions (explained later), they can do all of the work and send the changes to you for review before publishing them.</p>
<h2 id="heading-how-does-this-relate-to-google-analytics"><strong>How does this relate to Google Analytics?</strong></h2>
<p>There is no direct relation. But along with Google Analytics, GTM is another tool in the Google Marketing Platform and gives you the immediate ability to more easily manage your Google Analytics installation. GA comes with prebuilt tags inside GTM that make it a breeze to set up.</p>
<h2 id="heading-what-else-can-i-use-this-for"><strong>What else can I use this for?</strong></h2>
<p>Google Analytics is just one of many code snippets this can be used for. Ideally, you’re not going to write your entire site here. But you have the ability to pretty much do whatever you want on your own site as long as <a target="_blank" href="https://support.google.com/tagmanager/answer/6328489?hl=en">Google doesn’t deem it malware</a>.</p>
<p>Some other use cases include:</p>
<ul>
<li>Traffic visualization with <a target="_blank" href="https://www.crazyegg.com/">Crazy Egg</a> or <a target="_blank" href="https://www.hotjar.com/">Hot Jar</a></li>
<li>Conversion and remarketing pixels with <a target="_blank" href="https://ads.google.com/home/">Google Ads</a></li>
<li>A/B Testing with <a target="_blank" href="https://marketingplatform.google.com/about/optimize/">Google Optimize</a> or <a target="_blank" href="https://www.abtasty.com/">AB Tasty</a></li>
<li><a target="_blank" href="https://support.google.com/tagmanager/answer/7679411?hl=en">Client side error</a> tracking (and logging them)</li>
<li>GDPR compliance management</li>
</ul>
<p>There are many baked-in like the examples above, meaning you don’t even need to mess with code. Just add the IDs or settings and go. But for whatever custom solution or tag you need, you can always set up the HTML manually.</p>
<h2 id="heading-anything-i-need-to-know-before-jumping-in"><strong>Anything I need to know before jumping in?</strong></h2>
<p>Before jumping right in, let’s familiarize ourselves with a few key terms that will make this ride a little easier.</p>
<h3 id="heading-tags"><strong>Tags</strong></h3>
<p>Tags in GTM are your pixels or code snippets. A tag includes a single instance of a contained piece of code that is used for one function.</p>
<p><em>Example:</em> your Google Analytics snippet will be one tag and if you add Crazy Egg, that will be another tag.</p>
<h3 id="heading-variables"><strong>Variables</strong></h3>
<p>A variable is a name that you give a predetermined or dynamic value. The variable can be based on a variety of different things, hence the name “variable”. But it will function as a single name that you can give and reference that will never change when using it.</p>
<p><em>Example:</em> we’ll set up your Google Analytics ID as a variable, meaning you’ll use that variable within the GA tag itself. If you ever need to update that ID, you won’t need to modify the tag or any other tags that use the variable – you’ll only need to update the variable itself.</p>
<h3 id="heading-triggers"><strong>Triggers</strong></h3>
<p>Triggers are the event or action that make your tag fire or load. This can happen in a variety of ways, such as when all or a specific page loads, when something is clicked, or when you have a <a target="_blank" href="https://support.google.com/tagmanager/answer/7679219?hl=en">completely custom event</a> you fire with Javascript.</p>
<p><em>Example:</em> when we set up Google Analytics, our trigger will be when any page loads.</p>
<h3 id="heading-container"><strong>Container</strong></h3>
<p>GTM allows you to manage multiple “containers” or groups of tags within your organization. This is helpful when you have one company with a few different website properties.</p>
<p><em>Example:</em> you’re a small company under a parent company. The parent company wants to maintain one organization, but each smaller company gets their own container, as they have their individual needs for tags and code snippets.</p>
<h2 id="heading-how-do-i-get-set-up"><strong>How do I get set up?</strong></h2>
<h3 id="heading-getting-your-account-set-up"><strong>Getting your account set up</strong></h3>
<p>The first thing you’ll need to do is get your account set up. After getting to the <a target="_blank" href="https://tagmanager.google.com/">tag manager homepage</a>, you’ll probably want to use your preexisting Google account. If you’re in an organization setting it up for the organization, you most likely want to use your business email, otherwise your personal account works okay too.</p>
<p>Next, create a new GTM account:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-new-account.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager new account</em></p>
<p>Once there, fill out the form appropriately. The Account Name should represent the top level of your hierarchy and the container name should represent the specific installation instance.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-new-account-container.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager new account container</em></p>
<p>As for the target platform, choose whichever makes sense. If it’s a website or web app, Web makes the most sense here.</p>
<h3 id="heading-finding-and-installing-your-snippet"><strong>Finding and installing your snippet</strong></h3>
<p>As soon as you accept the terms and hit create, you’ll be presented with a snippet in a little modal. You'll want to do exactly what it says and install the snippets per the instructions.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-install-snippet.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager install snippet</em></p>
<p>Didn’t get the screen or accidentally exited out? You can find your snippet again by navigating to Admin in the top navbar and then click Install Google Tag Manager under Container to the right.</p>
<h3 id="heading-testing-that-its-working"><strong>Testing that it’s working</strong></h3>
<p>To make sure it’s working, let’s verify a few things:</p>
<ul>
<li>We created our account</li>
<li>We created our container</li>
<li>We installed the Google Tag Manager snippets on our page and the change are live</li>
</ul>
<p>Once all of those things are true, go ahead and click the Preview button in the top right of the page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-preview.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager preview</em></p>
<p>If successful, you’ll now see an orange banner at the top of the page that says you’re in Preview Mode:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-preview-mode.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager preview mode</em></p>
<p>Now wander over to the website that you installed GTM on and you should now see a banner at the bottom of the page. This will serve as your Debugger for working with GTM’s Preview.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-debugger.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager debugger</em></p>
<p>You should see something similar to that, which means it worked! ?</p>
<p>Note: if you have an ad blocker on, similar to GA, you may need to disable it on the page you’re installing on in order to see it working.</p>
<h2 id="heading-cool-its-working-what-about-google-analytics"><strong>Cool, it’s working, what about Google Analytics?</strong></h2>
<p>Now that we have a basic installation of GTM working, let’s set up Google Analytics. First we'll want to do some prep, so let's jump back over to the Tag Manager dashboard.</p>
<h3 id="heading-create-a-settings-variable"><strong>Create a settings variable</strong></h3>
<p>Navigate to Variables in the left sidebar and then click New beside User-Defined Variables.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-new-variable.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager new variable</em></p>
<p>For the name, enter “GA Settings” and under Variable Type, click through and select Google Analytics Settings. Enter your Google Analytics Tracking ID (or Property ID) in the appropriate field, and finally click Save, at which point you have your new settings variable.</p>
<h3 id="heading-create-a-new-ga-tag"><strong>Create a new GA tag</strong></h3>
<p>Navigate to Tags in the left sidebar and then click New beside Tags.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-new-tag.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager new tag</em></p>
<p>For the name, enter “GA - All Pages”. Under Tag Type, click and select Google Analytics: Universal Analytics in the panel that pops out from the right.</p>
<p>After selecting the tag type, under Google Analytics Settings, select your variable from the previous step, which if you followed along will be called “GA Settings”.</p>
<p>Next, click in the middle of the Triggering box, which should open a new UI to select a trigger.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-trigger.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager trigger</em></p>
<p>Select All Pages, which should be the only Trigger there if you’re in a new account. It will take you back to the New Tag UI with your newly selected trigger.</p>
<p>Once the above is done, click Save in the top right of the UI which will then save and create your new Google Analytics tag.</p>
<h3 id="heading-test-that-gtm-is-working"><strong>Test that GTM is working</strong></h3>
<p>Similar to when we installed GTM to begin with, let’s go back to the Workspace home by clicking Overview in the left sidebar. Then click Preview at the top right.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-debugger-google-analytics.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager debugger with Google Analytics</em></p>
<p>Open up your page GTM is installed on and you should once again see your Debugger, but this time with the Google Analytics Tag loading.</p>
<h2 id="heading-are-we-done-yet"><strong>Are we done yet?</strong></h2>
<p>Not quite. Although we have GA working, we need to tweak the configuration to make sure GA and GTM work correctly together.</p>
<h3 id="heading-updating-the-page-snippet"><strong>Updating the page snippet</strong></h3>
<p>Let’s dig into the code one more time to update our Google Analytics and Google Tag Manager snippets.</p>
<p>The issue with the installation that we set up here is that we installed GA through the GA instructions and GA inside GTM. This means we have GA installed twice. In practice, GA may send 1 pageview from your default installation and then another via GTM. To avoid this, we want to remove the pageview from the default GA snippet.</p>
<p>If you just have a super basic default installation, I did the work for you and you can go ahead and copy the snippet below. Replace <code>[YOUR GA PROPERTY ID]</code> with your GA Property ID and <code>[YOUR GTM CONTAINER ID]</code> with your GTM Container ID, and swap it out for your existing GA and GTM installation on your page.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-comment">// Set up an initial dataLayer configuration</span>
<span class="hljs-built_in">window</span>.dataLayer = <span class="hljs-built_in">window</span>.dataLayer || [{
  <span class="hljs-string">"gaPropertyId"</span>: <span class="hljs-string">"[YOUR GA PROPERTY ID]"</span>
}];

<span class="hljs-comment">// Configure gtag and your GA ID</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">gtag</span>(<span class="hljs-params"></span>)</span>{dataLayer.push(<span class="hljs-built_in">arguments</span>);}
gtag(<span class="hljs-string">'js'</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>());
gtag(<span class="hljs-string">'config'</span>, <span class="hljs-string">'[YOUR GA PROPERTY ID]'</span>);

<span class="hljs-comment">// Google Tag Manager snippet</span>
(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">w,d,s,l,i</span>)</span>{w[l]=w[l]||[];w[l].push({<span class="hljs-string">'gtm.start'</span>:
<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getTime(),<span class="hljs-attr">event</span>:<span class="hljs-string">'gtm.js'</span>});<span class="hljs-keyword">var</span> f=d.getElementsByTagName(s)[<span class="hljs-number">0</span>],
j=d.createElement(s),dl=l!=<span class="hljs-string">'dataLayer'</span>?<span class="hljs-string">'&amp;l='</span>+l:<span class="hljs-string">''</span>;j.async=<span class="hljs-literal">true</span>;j.src=
<span class="hljs-string">'https://www.googletagmanager.com/gtm.js?id='</span>+i+dl+<span class="hljs-string">'&amp;gtm_cookies_win=x'</span>;f.parentNode.insertBefore(j,f);
})(<span class="hljs-built_in">window</span>,<span class="hljs-built_in">document</span>,<span class="hljs-string">'script'</span>,<span class="hljs-string">'dataLayer'</span>, <span class="hljs-string">'[YOUR GTM CONTAINER ID]'</span>);
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>This should REPLACE your current Google Analytics snippet if you have one. If you don't, this should go as far in the top of your <code>&lt;head&gt;</code> tag as you can, but under the <code>charset</code> meta tag.</p>
<p>For more advanced users, just make sure you’re not sending duplicate pageviews or duplicate events between the page snippet and any GTM tag you create.</p>
<h3 id="heading-test-that-ga-is-working"><strong>Test that GA is working</strong></h3>
<p>Follow the steps above to make sure GA is showing up with the debugger.</p>
<p>The final thing you’ll want to do is make sure your installation is working using <a target="_blank" href="https://chrome.google.com/webstore/detail/tag-assistant-by-google/kejbdjndbnbjgmefkgdddjlbokphdefk?hl=en">Google’s Tag Assistant extension</a>. Once you install the extension, go back to your page and click Enable in the Extension’s UI.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-assistant-record.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Assistant enable recording</em></p>
<p>Refresh the page and you should see 2 tags, GA and GTM.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-assistant-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Assistant results</em></p>
<p>If you notice, my GA tag is blue and yours may be too. Click in to Google Analytics for more info.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-assistant-implementation.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Assistant non-standard implementation</em></p>
<p>As you can see, we have a healthy 1 Pageview Request and a note that says Non-standard implementation (hence the blue) This is because we installed it with GTM instead of the default on page.</p>
<h2 id="heading-publish-and-deploy"><strong>Publish and Deploy!</strong></h2>
<p>We’re there! Last step is to Publish your Container and make the changes live.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-submit.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager submit version</em></p>
<p>Click Submit in the Overview UI, enter a name and description.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/google-tag-manager-version-configuration.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Google Tag Manager version configuration</em></p>
<p>Finally click Publish and your changes will be live on your site!</p>
<h2 id="heading-what-else-do-i-need-to-know"><strong>What else do I need to know?</strong></h2>
<p>There’s plenty more to talk through, but that’s for a different day. There are a ton of resources online to get you started with adding your own new tags and exploring the capabilities of Google Analytics, but here are a few points to keep in mind with GTM.</p>
<h3 id="heading-permissions"><strong>Permissions</strong></h3>
<p>You most likely don’t want every marketer on your 1,000 person team to have publish access to your GTM container. It’s best to have one or a few people responsible for managing the container, reviewing, and publishing while keeping everyone else to a lower access role. This will help prevent accidental changes or abuse within a bigger team.</p>
<h3 id="heading-security"><strong>Security</strong></h3>
<p>Permissions are your first step towards maintaining a secure installation. But Google takes this an extra step and performs some actions for you, such as checking for code errors and <a target="_blank" href="https://support.google.com/tagmanager/answer/6328489?hl=en">scanning for malware</a>. While this is great, it’s still important to keep an active review cycle of tags getting published, just like any other pieces of code, to make sure the site integrity and health remain in tact.</p>
<h3 id="heading-conventions"><strong>Conventions</strong></h3>
<p>I highly recommend starting early with naming conventions and best practices when configuring your tags, variables, triggers, and really anything within GTM. The different ways to name things can spiral out of control really quickly, depending on how many people are working in there. This will make your work difficult to find, so it’s best to agree with the team on a convention to use early and get off on the right foot.</p>
<h3 id="heading-single-page-apps"><strong>Single Page Apps</strong></h3>
<p>This doesn’t account for the impact single page apps have on a GTM and GA setup. The trigger we set up here will fire when any page loads, which is defined by a new page load by the browser. Single page apps don’t actually load a new page – rather, the JavaScript within the app makes it appear that a new page loads, so the trigger here will only fire the first pageview. Though it doesn’t include information directly usable in GTM, the GA documentation has <a target="_blank" href="https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications">some good information</a> about tracking these types of apps.</p>
<h3 id="heading-gdpr"><strong>GDPR</strong></h3>
<p>While GTM alone does not (currently) violate GDPR, you still need to be cognizant of how any of the tags you use impact your standing. This guide doesn’t touch this, so please make sure to do your homework.</p>
<h3 id="heading-exiting-out-of-debugger"><strong>Exiting out of Debugger</strong></h3>
<p>Stuck? One way is to clear your cookies, but you should always be able to go to the GTM Overview page and hit "Leave Preview Mode” right under the orange Preview Mode banner at the top of the page.</p>
<h2 id="heading-whats-next"><strong>What's next?</strong></h2>
<p>From here, you can start managing your tags and pixels through GTM, which allows you to have a single source of consistent data flow into those tags. Experiment and use the debugger to play around, as it opens the door for a lot of new ways to work with the marketing side of things.</p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>

<p><em>Originally published at <a target="_blank" href="https://www.colbyfayock.com/2019/11/how-to-use-google-tag-manager-to-maintain-google-analytics-and-other-marketing-tags">https://www.colbyfayock.com/2019/11/how-to-use-google-tag-manager-to-maintain-google-analytics-and-other-marketing-tags</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
