<?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[ website development, - 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[ website development, - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 27 Jun 2026 11:23:45 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/website-development/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Deploy Your Websites and Apps – User-Friendly Deployment Strategies ]]>
                </title>
                <description>
                    <![CDATA[ Deploying your application is a key aspect of software development. Typically, having an app on your local system isn't enough – it needs to be accessible online. So choosing a suitable and user-friendly hosting and deployment plan is vital. The key ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-deploy-websites-and-applications/</link>
                <guid isPermaLink="false">66b9f47675413b5a1215b325</guid>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Applications ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ijeoma Igboagu ]]>
                </dc:creator>
                <pubDate>Wed, 09 Aug 2023 14:23:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/cover-friendly-deploy.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Deploying your application is a key aspect of software development. Typically, having an app on your local system isn't enough – it needs to be accessible online. So choosing a suitable and user-friendly hosting and deployment plan is vital.</p>
<p>The key to making the right decision lies in understanding the goal of your application. Perhaps it’s a simple website, a one-page app, or it requires serverless or cloud functions. Having clarity about these aspects will significantly ease the deployment process.</p>
<p>In this article, we will look at a few popular methods for deploying your application that will help tackle these challenges.</p>
<h2 id="heading-what-well-cover">What we'll cover:</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-to-consider-when-deploying-to-a-hosting-platform">What to consider when deploying a hosting platform</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-deploy-a-website-or-app-with-render">How to deploy a website or app with Render</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-deploy-a-website-or-app-with-surge">How to deploy a website or app with Surge</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-deploy-a-website-or-app-with-vercel">How to deploy a website or app with Vercel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-deploy-a-website-or-app-with-github-pages">How to deploy a website or app with GitHub Pages</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-deploy-a-website-or-app-with-netlify">How to deploy a website or app with Netlify</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-what-to-consider-when-deploying-to-a-hosting-platform">What to Consider when Deploying to a Hosting Platform</h2>
<p>There are several factors to take into account when selecting a hosting platform:</p>
<ol>
<li><p><strong>Purpose</strong>: Before you host your application, consider the technologies you used to build it and how much storage the platform can handle.</p>
</li>
<li><p><strong>Interface</strong>: A good interface is essential for a hosting platform. Look for a control panel or dashboard that allows you to easily administer your website.</p>
</li>
<li><p><strong>Reviews</strong>: Look at the hosting service's reviews and read what other clients have to say.</p>
</li>
<li><p><strong>Security</strong>: To safeguard your website and data, it is essential to have the right security measures in place.</p>
</li>
<li><p><strong>Support</strong>: You should always have someone there to help you out when you need it.</p>
</li>
</ol>
<h3 id="heading-why-is-deploying-an-application-important">Why is Deploying an Application Important?</h3>
<p>If you've built an app, there are various reasons you may want or need to deploy it, such as:</p>
<ol>
<li><p>It showcases professionalism and credibility to users.</p>
</li>
<li><p>It increases the accessibility of the application to a broader audience.</p>
</li>
<li><p>It enables user interaction and feedback.</p>
</li>
<li><p>It facilitates data analysis and provides insights for informed decision-making.</p>
</li>
<li><p>It identifies areas for improvement in the application.</p>
</li>
</ol>
<h3 id="heading-whats-the-benefit-of-choosing-a-user-friendly-deployment-method">What's the Benefit of Choosing a User-Friendly Deployment Method?</h3>
<p>Opting for a more approachable deployment method brings significant advantages:</p>
<ol>
<li><p><strong>Collaboration</strong>: When working together as a team, it’s useful to have straightforward methods to deploy your application. This makes collaboration and teamwork easy. These will encourage cooperation throughout the deployment process.</p>
</li>
<li><p><strong>Efficiency</strong>: A user-friendly deployment method simplifies the process.</p>
</li>
<li><p><strong>Simplicity</strong>: Choosing a hosting platform that is easy to understand will benefit everyone involved.</p>
</li>
<li><p><strong>Reliability</strong>: easy to use deployment methods ensure a more reliable application and minimise potential disruptions.</p>
</li>
</ol>
<h2 id="heading-how-to-deploy-a-website-or-app-with-render">How to Deploy a Website or App with Render</h2>
<p>Render provides an interface for quick and straightforward publishing of static web content. Let's now go through how to deploy an app to Render step by step.</p>
<p>Step 1: First, ensure you have deployed your work or code from your editor to your GitHub account.</p>
<p>Step 2: Open a new browser tab and navigate to the <a target="_blank" href="https://render.com/">Render website</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743002851078/4bf085d2-7c38-432b-93bf-95f2b02368e7.gif" alt="render website" class="image--center mx-auto" width="1920" height="920" loading="lazy"></p>
<p><em>Render website</em></p>
<p>Step 3: Select the “GET STARTED” button on Render's home page to get going.</p>
<ul>
<li><p>You can use your GitHub, GitLab, or Bitbucket account when signing up. Choose the GitHub option and follow the steps to grant Render access to your GitHub account.</p>
</li>
<li><p>If you already have a Render account, click the “Sign in” button to be redirected to the Sign-in page. You can sign in via email and authenticate using your Google account or your GitHub account.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743002894595/542d8097-4fcc-409a-bc80-a599656152c9.gif" alt="Render sign in page" class="image--center mx-auto" width="1920" height="991" loading="lazy"></p>
<p><em>Sign in page</em></p>
<p>Step 4: Once you access the dashboard, click the “New” button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743002941009/36239b95-8cf3-4633-9b27-fb966a133270.png" alt="Render dashboard" class="image--center mx-auto" width="1704" height="536" loading="lazy"></p>
<p><em>Dashboard of Render</em></p>
<p>Step 5: Upon doing so, a drop-down menu will appear. It'll show you a comprehensive list of services provided by Render.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003263069/d8053161-5ef1-4c1b-a047-c635c75df2eb.png" alt="List of services offered by render" class="image--center mx-auto" width="1600" height="481" loading="lazy"></p>
<p><em>List of Services offered by render</em></p>
<p>Step 6: Clicking “Static Site” from the drop-down menu will lead you to the “Create a New Static Site” page. From there, you can select the repository you wish to host.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003315411/fe9a7eb8-2303-48ad-b83a-fb471e821e05.png" alt="Create a new static site page" class="image--center mx-auto" width="1600" height="826" loading="lazy"></p>
<p><em>Create a New Static Site</em></p>
<p>Step 7: After selecting the repository you wish to host, you will be directed to the deployment platform. There, you can provide the necessary information to host the application and click the “Create Static Site” button for it to deploy.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003358045/c37346e8-5793-40a3-95fc-17c388b110ed.png" alt="Render deployment" class="image--center mx-auto" width="1838" height="1292" loading="lazy"></p>
<p><em>Deploying the app using Render</em></p>
<p>Here's what the final output should look like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003407878/76f120fe-8754-4e7c-8746-6107f47d7425.png" alt="Hosted application" class="image--center mx-auto" width="893" height="759" loading="lazy"></p>
<p><em>Hosted application</em></p>
<h3 id="heading-pros-of-deploying-with-render">Pros of Deploying With Render</h3>
<ul>
<li><p>Render has a free tier for hosting basic static websites.</p>
</li>
<li><p>It provides a flexible price structure that ensures transparency and cost-effectiveness.</p>
</li>
<li><p>It makes deployment easy. They provide an interface and connection with standard development tools and platforms. It also supports a wide range of programming languages, frameworks, and databases.</p>
</li>
<li><p>It delivers a variety of integrated features that improve the hosting experience.</p>
</li>
<li><p>It has good customer service support.</p>
</li>
</ul>
<h3 id="heading-cons-of-deploying-with-render">Cons of Deploying With Render</h3>
<ul>
<li><p>Render specializes in static websites, Docker containers, and serverless functions.</p>
</li>
<li><p>For more complex/bigger applications, there's a paid plan. You'll need to go through their price structure and understand the charges related to your usage.</p>
</li>
<li><p>There is a learning curve, especially for newcomers to the platform.</p>
</li>
</ul>
<h2 id="heading-how-to-deploy-a-website-or-app-with-surge">How to Deploy a Website or App with Surge</h2>
<p>This friendly platform and tool make it quick and easy to deploy static websites online.</p>
<p>Deploying your static files to <a target="_blank" href="https://https//surge.sh/">surge.sh</a> is easy using the command-line interface (CLI).</p>
<p>This command-line interface (CLI) streamlines the process of hosting and distributing your online projects.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003449591/4825b5da-69a7-4780-924c-8c2206c82a96.png" alt="Surge website" class="image--center mx-auto" width="1600" height="825" loading="lazy"></p>
<p><em>Surge website</em></p>
<h3 id="heading-steps-to-deploy-your-site-using-surge">Steps to Deploy Your Site Using Surge</h3>
<p>First, in the terminal of your project, type the command <code>npm i -g surge</code>.</p>
<p>Then type the command <code>surge</code>.</p>
<p>And that's it! You can deploy your app without logging in into your GitHub account.</p>
<p>To see what you have deployed, first copy the successful link in the terminal. Then paste it into your browser. You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003506734/70e7d551-2aa9-4023-980c-53a8fdd34d2d.png" alt="Hosted site with Surge" class="image--center mx-auto" width="1231" height="467" loading="lazy"></p>
<p><em>Hosted site with Surge</em></p>
<p>Like I mentioned before, Surge doesn't need extra code. You can easily deploy your app right from your editor's terminal by typing the command <code>surge</code>.</p>
<h3 id="heading-pros-of-deploying-with-surge">Pros of Deploying with Surge</h3>
<ul>
<li><p><strong>Easy to Use:</strong> Surge provides a simple deployment for static websites.</p>
</li>
<li><p><strong>Fast Deployment:</strong> It has a quick deployment time.</p>
</li>
<li><p><strong>Custom Domains:</strong> It allows you to use your domain name for your website.</p>
</li>
<li><p><strong>SSL Support:</strong> It provides free SSL certificates.</p>
</li>
<li><p><strong>Support for Single-Page Applications (SPAs):</strong> It's well-suited for deploying single-page applications.</p>
</li>
</ul>
<h3 id="heading-cons-of-deploying-with-surge">Cons of Deploying with Surge</h3>
<ul>
<li><p><strong>Limited Functions:</strong> Surge is designed for static websites.</p>
</li>
<li><p><strong>No Custom Server Configurations:</strong> It streamlines the deployment process by abstracting away server configurations.</p>
</li>
<li><p><strong>Premium Features:</strong> This platform offers free hosting for basic usage, but you'll have to pay for more features.</p>
</li>
</ul>
<h2 id="heading-how-to-deploy-a-website-or-app-with-vercel">How to Deploy a Website or App with Vercel</h2>
<p>Vercel is a hosting and deployment platform that specializes in modern web applications.</p>
<p>It is particularly well-suited for single-page applications, serverless operations, and static websites. It integrates with popular frameworks like Next.js and Gatsby.js, making deployments fast and simple.</p>
<h3 id="heading-steps-to-deploy-your-site-using-vercel">Steps to Deploy Your Site Using Vercel</h3>
<p>First, ensure that you have deployed your work or code from your editor to your GitHub account.</p>
<p>Then open a new browser tab and navigate to <a target="_blank" href="https://vercel.com/">Vercel’s website</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003556995/7c48e8dc-6955-45c2-a068-c6c1b0e15cf6.png" alt="Vercel website" class="image--center mx-auto" width="1600" height="818" loading="lazy"></p>
<p><em>Vercel website</em></p>
<p>Head to the Vercel website and click the “Sign up” button on the homepage.</p>
<ul>
<li><p>Sign up using your GitHub account and follow the steps to grant Vercel access to your GitHub account. If you already have a Vercel account, click the “Login” button and enter your login information.</p>
</li>
<li><p>After signing up or logging in, Vercel will request access to specific information from your GitHub account. Review the required permissions and permit Vercel to proceed.</p>
</li>
</ul>
<p>Next, click on “Add New…” on the Vercel dashboard. This action will reveal a drop-down menu. From the menu, select “Project,” which will navigate you to the next page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003587862/a04db892-e3fe-4218-a60f-ed134e143006.gif" alt="Vercel add new project" class="image--center mx-auto" width="1920" height="991" loading="lazy"></p>
<p><em>Add New Project</em></p>
<p>On the next page, you will import your repository for deployment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003630267/265499e1-d1cd-4083-a05c-68dc4c9e9741.gif" alt="Vercel deployment" class="image--center mx-auto" width="1920" height="991" loading="lazy"></p>
<p><em>Vercel Deployment</em></p>
<p>Here's what the final output should look like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003666437/b418d602-42ca-4610-ae43-dc69bed0d954.gif" alt="Vercel hosted site" class="image--center mx-auto" width="1920" height="991" loading="lazy"></p>
<p><em>Hosted site</em></p>
<p>When deploying your application to Vercel, you may encounter some errors, often caused by routing issues.</p>
<p><strong>To fix this:</strong></p>
<ul>
<li><p>Create a file under the root of your application called <code>vercel.json</code>.</p>
</li>
<li><p>Inside the file, write the following code:</p>
</li>
</ul>
<p><code>vercel.json</code></p>
<pre><code class="lang-bash">{ <span class="hljs-string">"rewrites"</span>: [{ <span class="hljs-string">"source"</span>: <span class="hljs-string">"/(.*)"</span>, <span class="hljs-string">"destination"</span>: <span class="hljs-string">"/"</span> }] }
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003723518/6c44d496-331e-4d09-b221-f3c3dc6c688c.png" alt="Vercel error fix" class="image--center mx-auto" width="1743" height="826" loading="lazy"></p>
<p><em>Inside your editor</em></p>
<h3 id="heading-pros-of-deploying-with-vercel">Pros of Deploying With Vercel</h3>
<ul>
<li><p><strong>Collaboration:</strong> Vercel offers tools for effective teamwork, access control, and cooperative deployments.</p>
</li>
<li><p><strong>Simple Deployment:</strong> it simplifies delivering your web apps with ease.</p>
</li>
<li><p><strong>Preview Deployments:</strong> it allows you to share and review changes before they go live. This promotes collaboration and ensures a smooth and efficient workflow.</p>
</li>
<li><p><strong>Scalability and Performance:</strong> It still guarantees great performance even with a large number of people using it.</p>
</li>
<li><p><strong>Git Integration:</strong> it makes Git integration easy.</p>
</li>
</ul>
<h3 id="heading-cons-of-deploying-with-vercel">Cons of Deploying With Vercel</h3>
<ul>
<li><p>If you are new to Vercel, you must understand how to deploy and configure your application. Reading <a target="_blank" href="https://vercel.com/docs">Vercel’s documentation</a> can help you get up to speed.</p>
</li>
<li><p>Vercel is great for small to medium-sized projects, but it may not be the best fit for large-scale applications with complex backend needs. In such cases, developers may need a hosting solution that offers more customization and scalability.</p>
</li>
</ul>
<h2 id="heading-how-to-deploy-a-website-or-app-with-github-pages">How to Deploy a Website or App with GitHub Pages</h2>
<p>GitHub Pages is a straightforward and cost-free hosting service. You can use it to host static web pages or documentation.</p>
<p>You can publish your site using GitHub Pages by submitting your code to a GitHub account and setting up a repository. Let's go through the process now.</p>
<h3 id="heading-steps-to-deploy-your-site-using-github-pages">Steps to Deploy Your Site Using GitHub Pages</h3>
<p>To use GitHub Pages to host your website, follow these simple steps:</p>
<p>First, go to GitHub's <a target="_blank" href="https://https//github.com/">website</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003758359/0d8d7328-a8ad-4b79-a814-3a55b3a04bb1.png" alt="GitHub landing page" class="image--center mx-auto" width="1835" height="483" loading="lazy"></p>
<p><em>Github website</em></p>
<p>Then create a GitHub repository. If you don’t have a GitHub account, you'll need to click on “sign up”, or just click “sign in” if you already have an account.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003801213/5362aa34-2ec8-430f-8809-01b42f574495.png" alt="Github signin button and signup buttons" class="image--center mx-auto" width="233" height="127" loading="lazy"></p>
<p><em>Github sign in button and sign up buttons</em></p>
<p>Create a new repository by clicking the New button in the upper-right corner of your GitHub profile.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003843884/8c918dbf-64bf-40c8-8f32-25fa6fef157d.png" alt="Creating a new repo" class="image--center mx-auto" width="594" height="428" loading="lazy"></p>
<p><em>Creating a new repository</em></p>
<p>Give your repository a name that reflects your website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003887101/51f0ab61-14b5-420c-95fb-27926b4dc566.gif" alt="Entering repo name on GitHub" class="image--center mx-auto" width="1920" height="991" loading="lazy"></p>
<p><em>Repository name</em></p>
<p>Once you have finished the previous step, go back to your Editor. Copy the generated code and paste it into your editor.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003942149/3c063b52-2bc2-4897-84af-e30ca8da18cd.png" alt="Code generated from new repository" class="image--center mx-auto" width="1600" height="142" loading="lazy"></p>
<p><em>Code generated from new repository</em></p>
<p>The code in the image above is generated when creating a new repository.</p>
<p>Go to the settings page of the newly created repository.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743003981000/6a55ae7c-2b69-44bd-bbe2-deaa695b63a5.png" alt="GitHub repo settings" class="image--center mx-auto" width="1600" height="766" loading="lazy"></p>
<p><em>Clicking on settings</em></p>
<p>Click on the settings option to redirect to the settings section. Locate and click on “Pages” in the left-hand side menu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004028760/9130f72b-0e6a-4a18-a72a-da948eb67fec.gif" alt="Settings section GitHub pages" class="image--center mx-auto" width="1920" height="920" loading="lazy"></p>
<p><em>GitHub pages section on the settings page</em></p>
<p>To access GitHub Pages, click on the “Pages” section. Once you’re on the GitHub Pages section, click in the drop-down menu and choose either the “master” or “main” branch. Remember to save your selection.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004108894/40fa0220-afba-4932-8900-1106046cf9e0.gif" alt="Enabling GitHub Pages to host your site" class="image--center mx-auto" width="1920" height="920" loading="lazy"></p>
<p><em>Enabling GitHub Pages to host your site</em></p>
<p>Refresh the page to find the link leading to your published website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004156941/3364fd42-d47e-40ea-b147-0fc0fa4f25c6.gif" alt="GitHub seeing your hosted site" class="image--center mx-auto" width="1920" height="920" loading="lazy"></p>
<p><em>Seeing your hosted site</em></p>
<h3 id="heading-pros-of-deploying-with-github-pages">Pros of Deploying With GitHub Pages</h3>
<ul>
<li><p>GitHub Pages are simple to set up – and you can build your website there.</p>
</li>
<li><p>It's free.</p>
</li>
<li><p>GitHub’s version control system makes it simple to keep track of changes and work with others.</p>
</li>
<li><p>GitHub Pages updates your website’s code whenever you make changes to it.</p>
</li>
<li><p>It offers collaboration on projects with other developers.</p>
</li>
<li><p>It ensures your website is safe through <code>HTTPS</code> (Hyper Text Transfer Protocol) encryption.</p>
</li>
</ul>
<h3 id="heading-cons-of-deploying-with-github-pages">Cons of Deploying With GitHub Pages</h3>
<p>While GitHub Pages offer many advantages, there are a few considerations to keep in mind:</p>
<ul>
<li><p>If your website becomes too large due to file size, this can cause some performance issues.</p>
</li>
<li><p>GitHub Pages may only support simple functions.</p>
</li>
<li><p>Understanding Git, the version control system used by GitHub, is essential for managing your website’s code.</p>
</li>
</ul>
<h2 id="heading-how-to-deploy-a-website-or-app-with-netlify">How to Deploy a Website or App with Netlify</h2>
<p>Netlify integrates with Git repositories and works well with static web pages and single-page apps.</p>
<h3 id="heading-steps-to-deploy-your-site-using-netlify">Steps to Deploy Your Site Using Netlify</h3>
<p>First, you'll need to make sure that you have deployed your work or code from your editor to your GitHub account.</p>
<p>Then, open a new browser tab and navigate to the <a target="_blank" href="https://www.netlify.com/">Netlify website</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004199311/04a14b1c-d034-4274-8657-1a9eeaaf1839.png" alt="Netlify website" class="image--center mx-auto" width="1600" height="825" loading="lazy"></p>
<p><em>Netlify website</em></p>
<p>Head to the Netlify website and click the “Sign up” button on the homepage.</p>
<ul>
<li><p>Create an account by signing up with your GitHub, GitLab, or Bitbucket credentials.</p>
</li>
<li><p>Select the GitHub option and follow the steps to grant Netlify access to your GitHub account.</p>
</li>
<li><p>If you already have a Netlify account, click the “Login” button and enter your login information. After signing up or logging in, Netlify will request access to specific information from your GitHub account. Review the required permissions and permit Netlify to proceed.</p>
</li>
</ul>
<p>Once you have finished registering, go to the dashboard where you will host your repository.</p>
<p>Netlify has two ways to host your project:</p>
<ol>
<li><p>Drag-n-drop</p>
</li>
<li><p>Importing the source code from your repository to the site.</p>
</li>
</ol>
<h4 id="heading-using-the-drag-n-drop-feature">Using the Drag-n-Drop feature:</h4>
<p>Once you have logged in, navigate to the left-hand side of the dashboard and select the “site” option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004230273/ef1debf2-c475-4cd1-8930-4b5c0fd2c412.png" alt="Netlify dashboard" class="image--center mx-auto" width="1600" height="766" loading="lazy"></p>
<p><em>Netlify dashboard</em></p>
<p>Before deploying your project, it’s important to include an “index.html” file. Netlify recognizes this file as the main folder for hosting your project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004285308/0387adf5-f015-44e0-bb91-1fb718bfdc04.png" alt="Root index.html file" class="image--center mx-auto" width="1485" height="620" loading="lazy"></p>
<p><em>Root</em> <code>index.html</code> <em>file</em></p>
<p>Go back to the website click on “site” and scroll down, you will see the drag-n-drop zone where you can drag and drop your file or you upload the folder.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004356707/d7285059-51a0-4802-af41-1d81b560754f.png" alt="Netlify drag and drop" class="image--center mx-auto" width="1872" height="567" loading="lazy"></p>
<p><em>Netlify drag and drop</em></p>
<p>By using this feature your project will be deployed.</p>
<h4 id="heading-importing-the-source-code-from-your-repository-to-the-site">Importing the source code from your repository to the site:</h4>
<p>First, upload your code to GitHub.</p>
<p>Then access the Netlify dashboard.</p>
<p>To access the option (drop-down) menu, click on “Add New Site”. Select “Import existing project.”</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004398011/0de1ad8d-3f36-47e9-8faa-626b399fb27e.png" alt="Netlify import existing project" class="image--center mx-auto" width="1600" height="812" loading="lazy"></p>
<p><em>Import existing project</em></p>
<p>When you click on “Import existing project,” the system will direct you to a new page. Then you can import your repository from your GitHub account or any other storage account where you stored your source code.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004440693/669cf508-588e-47f9-8542-24552c073009.png" alt="Netlify connect to Git provider" class="image--center mx-auto" width="1600" height="825" loading="lazy"></p>
<p><em>Connect to Git provider</em></p>
<p>When you click on this button, it will navigate you to the next page where you can choose the desired repository from the available options.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004493978/578f1241-8b07-432d-a40a-ed6549aecb53.png" alt="578f1241-8b07-432d-a40a-ed6549aecb53" class="image--center mx-auto" width="1920" height="990" loading="lazy"></p>
<p><em>Choosing repository from Netlify</em></p>
<p>After selecting the repository, the next step is configuring and deploying your site.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004531244/4f5d1691-6cd7-4c86-8be8-fa423a6e8772.gif" alt="Deploying from Netlify" class="image--center mx-auto" width="1920" height="920" loading="lazy"></p>
<p><em>Deploying from Netlify</em></p>
<p>Here's the result:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004569842/d7f6c8cf-855e-4d12-847b-9ec22b6bc177.gif" alt="Netlify hosted app" class="image--center mx-auto" width="1920" height="920" loading="lazy"></p>
<p><em>Hosted App</em></p>
<p>When deploying your application to Netlify, you may encounter errors, often caused by routing issues.</p>
<p><strong>To fix this:</strong></p>
<p>Create a file called <code>_redirects</code>, and inside write the following code:</p>
<p><code>_redirect file</code></p>
<pre><code class="lang-bash">/* /index.html 200
</code></pre>
<p><strong>Example</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743004628305/2fa06275-812f-42ed-8bf0-b30765a0a821.png" alt="Encounter error during deployment which is caused by routing issue" class="image--center mx-auto" width="1280" height="491" loading="lazy"></p>
<p><em>Encounter error during deployment which is caused by routing issue</em></p>
<h3 id="heading-pros-of-deploying-with-netlify">Pros of Deploying with Netlify</h3>
<ul>
<li><p><strong>Form handling capabilities:</strong> Netlify makes handling forms on your websites easy. It has a simple API that allows you to collect and process form submissions. It also integrates with popular form providers like Zapier, Mailchimp, and Slack.</p>
</li>
<li><p><strong>It’s easy to configure custom domains for your websites</strong>: it makes it simple to manage your website’s domain and security. It also ensures that your websites are secure with <code>HTTPS</code>.</p>
</li>
<li><p><strong>Web Hosting:</strong> Netlify helps you host your websites and applications. It offers static site hosting, allowing you to deploy <code>HTML</code>, <code>CSS</code>, and <code>JavaScript</code> files straight from a Git repository or by drag-and-drop.</p>
</li>
<li><p><strong>Simple Deployment:</strong> it makes deploying your website or web app straightforward. When you connect your repository, it will deploy any changes you make.</p>
</li>
<li><p><strong>Continuous Deployment:</strong> When you make updates to your source code, Netlify builds and publishes your website for you. This ensures that your website always reflects the latest changes you’ve made.</p>
</li>
</ul>
<h3 id="heading-cons-of-deploying-with-netlify">Cons of Deploying With Netlify</h3>
<ul>
<li><p><strong>Project size:</strong> This hosting platform is an excellent choice for small to medium-sized projects. But you should explore other hosting and deployment options as your website or app grows.</p>
</li>
<li><p><strong>Limited Backend Capabilities:</strong> Netlify prioritizes front-end development and static websites. Although it does have some backend functions, it may not be the best option for projects that need complex server-side processing.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, deploying an application is crucial so that users can access it and others can see your work. User-friendly deployment methods offer significant benefits, including collaboration, efficiency, simplicity, and reliability.</p>
<p>Here's a quick review of what we've covered here:</p>
<ul>
<li><p>Render offers a simple interface, affordable pricing, and built-in features.</p>
</li>
<li><p>Surge offers fast deployment speeds, making deploying static websites a breeze.</p>
</li>
<li><p>Vercel is an expert in creating cutting-edge web apps with scalability and preview deployments.</p>
</li>
<li><p>If you’re looking for an easy-to-use option, consider GitHub Pages. It provides several advantages, including simplicity, free hosting, version control, and <code>HTTPS</code> encryption. But, it has limited functionality and technological limitations for more sophisticated applications.</p>
</li>
<li><p>Netlify is a user-friendly platform that's great for quickly deploying static websites and web apps. It's perfect for projects that want easy setup, automatic deployment, and modern development features</p>
</li>
</ul>
<p>What you choose will depend on the particular needs and objectives of your application and the technical know-how of the developers working on it.</p>
<p>And if you want to improve your Git skills, you can read this Git Command article.</p>
<p>If you found this tutorial helpful, please share it with fellow developers who may also find it interesting. You can also stay updated on my latest projects by following me on <a target="_blank" href="https://https//twitter.com/ijaydimples">Twitter</a> and <a target="_blank" href="https://https//www.linkedin.com/in/ijeoma-igboagu/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Website Free of Cost – Website Builder Platform Guide ]]>
                </title>
                <description>
                    <![CDATA[ If you are interested in creating a website that requires no coding at all, then you can use a free website builder. In this article, I will provide you with a list of four free website builders you can choose from when creating your websites. Here i... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-website-free-of-cost-website-builder-platform-guide/</link>
                <guid isPermaLink="false">66b8d9768cd1c2aa053d49b8</guid>
                
                    <category>
                        <![CDATA[ No Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Website design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jessica Wilkins ]]>
                </dc:creator>
                <pubDate>Tue, 16 Nov 2021 15:53:09 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/11/andrew-neel-cckf4TsHAuw-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you are interested in creating a website that requires no coding at all, then you can use a free website builder.</p>
<p>In this article, I will provide you with a list of four free website builders you can choose from when creating your websites.</p>
<p>Here is the complete list. If you find an option you like, then click on the link and it will take you to that section of the article.</p>
<ol>
<li><a class="post-section-overview" href="#heading-wix">Wix</a></li>
<li><a class="post-section-overview" href="#heading-weebly">Weebly</a></li>
<li><a class="post-section-overview" href="#heading-site123">SITE123</a></li>
<li><a class="post-section-overview" href="#heading-carrd">Carrd</a></li>
</ol>
<h2 id="heading-wix">Wix</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-12.54.06-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://www.wix.com/">Wix</a> was founded in 2006, and it is a very popular free drag and drop website builder.</p>
<p>The free version comes with the following options:</p>
<ul>
<li>Up to 500 MB (megabytes) of storage and bandwidth </li>
<li>Assigned URL: accountname.wixsite.com/siteaddress</li>
<li>Wix ads appearing on every page</li>
</ul>
<p>You can sign up using an email address and password or with Facebook, Google or Apple.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.06.05-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you want to create a new website, you will be walked through a questionnaire to create the basic setup.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.08.02-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You have the option to design your website choosing from 100's of templates and drag and drop features. Or you can choose the [Wix Artificial Design Intelligence](https://support.wix.com/en/article/about-wix-adi#:~:text=Wix%20Artificial%20Design%20Intelligence%20(ADI,a%20stunning%20site%20for%20you!&amp;text=From%20billions%20of%20combinations%20including,%2Da%2Dkind%20free%20site!) which will create a website for you. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.11.36-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you choose the [Wix Artificial Design Intelligence](https://support.wix.com/en/article/about-wix-adi#:~:text=Wix%20Artificial%20Design%20Intelligence%20(ADI,a%20stunning%20site%20for%20you!&amp;text=From%20billions%20of%20combinations%20including,%2Da%2Dkind%20free%20site!) option, then you will be asked a series of questions on what kinds of design themes and features you are interested in.</p>
<p>Once you choose your templates, then the Wix ADI will create your basic website where you can customize the pages. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.16.29-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can also see what these sites would look like on mobile devices.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.17.28-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you choose to use the template editor, you can browse through hundreds of free templates and customize them to your liking. You can also add your own media including videos and images. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.20.21-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>When you are finished creating your site, click on Publish in the upper right hand corner of the page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.22.13-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>It is easy to get your website up and running using clean, professional designs and there is no coding knowledge necessary.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.25.06-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-weebly">Weebly</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.42.34-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://www.weebly.com/">Weebly</a> was founded in 2006 and it is a free website builder that makes it easy to build blogs, online stores, and personal sites using customizable templates. </p>
<p>The free account will provide the following options:</p>
<ul>
<li>SSL security</li>
<li>Access to the community forum</li>
<li>Access to dozens of website templates</li>
<li>Chat and Email support</li>
</ul>
<p>You can create your own account using a username and password or you can login with Facebook, Google, or Square. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.47.29-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once you are signed in, then you can choose between a business website or personal.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.50.25-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>There are dozens of themes to choose from that you can customize to your liking.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.51.24-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the Weebly editor, you can add media like videos, images, files and more. You can also add features like social icons, search boxes and forms. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-1.55.56-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once you are done customizing your website, then you click on Publish located in the upper right hand corner. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.07.36-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-site123">SITE123</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.28.25-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://www.site123.com/">SITE123</a> was founded in 2015 and is a free website builder that gives you access to dozens of templates and layouts to choose from. </p>
<p>The free version comes with the following features:</p>
<ul>
<li>250 MB Storage</li>
<li>250 MB Bandwidth</li>
<li>24/7 Live chat support</li>
</ul>
<p>To get started, you can choose what kind of website you want to build.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.33.12-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can choose your website name.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.33.44-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can sign up with an email and password or with Facebook or Google. Once you are signed in then you can customize your website.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.35.49-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can also preview what it would look like in desktop, tablet, or mobile view.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.36.41-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once you are done editing your website, then you can publish it by clicking on the green publish button in the upper right hand corner. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.37.44-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you are interested in adding a custom domain for your site, then you will need to pay for that.</p>
<h2 id="heading-carrd">Carrd</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.54.01-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://carrd.co/">Carrd</a> is a free website builder where you can browser through dozens of templates and create one-page websites. </p>
<p>You can create a free account by using your name, email, and password.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.56.21-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once you are signed in, then you can choose from dozens of templates.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.57.55-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can then modify the template by changing colors, fonts, and adding images.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.58.57-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>When you are done editing your page, click on the publish option located in the upper right hand corner. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-15-at-2.59.44-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you are interested in having custom domains, Google analytics, and custom forms, then you can sign up for the <a target="_blank" href="https://carrd.co/pro">pro version</a>.</p>
<p>I hope you enjoyed this article on free Website builders.  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Different Ways to Charge for a Website Project – Freelance Developer Guide ]]>
                </title>
                <description>
                    <![CDATA[ By Kyle Prinsloo As someone who offers a service as a freelancer, you have a major say in how you price a website project. But how do you go about charging for a website project? Sure, you can bill by the hour, but is there a better way? In this ]]>
                </description>
                <link>https://www.freecodecamp.org/news/different-ways-to-charge-for-a-website/</link>
                <guid isPermaLink="false">66d46019264384a65d5a9590</guid>
                
                    <category>
                        <![CDATA[ Freelancing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 02 Nov 2021 16:37:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/10/ux-indonesia-qC2n6RQU4Vw-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Kyle Prinsloo</p>
<p>As someone who offers a service as a <a target="_blank" href="https://studywebdevelopment.com/how-to-start-freelancing-as-developer.html">freelancer</a>, you have a major say in how you price a website project.</p>
<p>But how do you go about charging for a website project?</p>
<p>Sure, you can bill by the hour, but is there a better way?</p>
<p>In this article, we are going to do an analysis of the different pricing options available to you as a developer to see which option is best for you.</p>
<p>But before we go over the different ways to charge for a website project, let's take a look at the factors that can help you decide how you <a target="_blank" href="https://studywebdevelopment.com/how-to-charge-for-a-website.html">price your web design services</a>.</p>
<p>Here's a 20-min video if you'd like to get an overview:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/43QIf9JNfwo" 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-what-to-consider-when-pricing-your-website-project">What to Consider When Pricing your Website Project</h2>
<h3 id="heading-skills-and-experience">Skills and Experience</h3>
<p>The more skills and experience you have, the more clients are willing to pay.</p>
<p>I don't mind paying a few more bucks if I know that this individual or company produces world-class results.</p>
<p>Why settle for something cheap when you can go with a reasonable option because it would be of the best quality?</p>
<p>It might be true that some website projects can be done in a week or two, but it doesn't mean it's of any less value than those that take a month or more.</p>
<p>Remember that clients are paying for your skills and years of experience, not the amount of time the project takes to be built (more on this later).</p>
<h3 id="heading-type-and-complexity-of-website">Type and Complexity of Website</h3>
<p>Your pricing depends on the type and complexity of websites you create.</p>
<p>Whether it's a personal blog, an e-commerce website, small or big business website, it requires time and effort.</p>
<p>Complex websites require more work and maintenance to keep them online.</p>
<h3 id="heading-scope-and-size">Scope and Size</h3>
<p>There are times when a project stretches beyond the initial timeframe required. In those cases, you might want to plan for this outcome or try to avoid such a situation.</p>
<p>Now let's move on to a few advantages and disadvantages to help you make a better informed decision on the pricing strategy you choose.</p>
<h2 id="heading-hourly-based-pricing">Hourly-Based Pricing</h2>
<p>Hourly-based pricing is the most popular pricing method and the easiest to understand and start with.</p>
<p>I'm going to discuss the disadvantages of using an hourly-based pricing approach before I present its advantages and what I believe is a better method.</p>
<h3 id="heading-hourly-billing-can-be-harmful-to-your-client-relationship">Hourly Billing Can be Harmful to Your Client Relationship</h3>
<p>Billing by the hour has the potential to be harmful to your client relationship.</p>
<p>Why?</p>
<p>The longer a project takes, the better it is for you and the worse it is for your client.</p>
<p>If your estimates are inaccurate, this causes trust problems that weaken the relationship over time.</p>
<p>This can happen in a variety of ways, but it's amplified when the client doesn't realize how long it'll take to implement a feature or change, leading them to believe you're working slowly on purpose.</p>
<p>Another way this can happen is if the project takes longer than expected, because your client might feel that you're exploiting them. Your client will begin to evaluate the timesheets you supplied them in search of inconsistencies, and trust will be weakened.</p>
<p>Plus, it also produces so many issues.</p>
<p>Even if you can prove X task took 4 hours, they can dispute it and say it should have taken 1 hour.</p>
<h3 id="heading-hourly-billing-discourages-efficiency-and-innovation">Hourly Billing Discourages Efficiency and Innovation</h3>
<p>You don't get rewarded for finding time-efficient ways to finish a project. If anything, you're getting financially punished.</p>
<p>Some websites can be completed in a few hours or a few days if you know what you're doing. If you're charging by the hour, what incentive do you have to find a way to complete the project in the shortest amount of time?</p>
<p>If you price your projects by the hour, you will, as a more experienced developer, get projects done sooner meaning you earn less per project.</p>
<p>So you think you make up for this by charging more per hour?</p>
<p>Well, this might only serve to scare your future (or even current) clients off to another developer who charges less per hour.</p>
<p>If anything, even if you don't do it intentionally, your work rate and efficiency will not be something you're too concerned about optimizing.</p>
<p>Besides, hourly work normally requires time and screen trackers.</p>
<p><strong>Example:</strong></p>
<p>Imagine you're working on a project that has similarities to a previous project you worked on or maybe there's a plugin or template you can use to cut your time spent on the project by half.</p>
<p>But by doing so, you'd cut down the number of hours you'd spend on your current project.</p>
<p>In this way, you've directly lowered your income because of a better, more efficient way to build a website.</p>
<h3 id="heading-your-income-is-capped">Your Income is Capped</h3>
<p>Hourly billing places an artificial limit on your income!</p>
<p>Let me explain.</p>
<p>There are only so many hours you can work in a year.</p>
<p>By providing a price per hour, you're limiting how much you're practically able to earn each year.</p>
<p>If you suddenly decided to increase your hourly rate because you'd like to <a target="_blank" href="https://studywebdevelopment.com/how-to-start-freelancing-as-developer.html">start earning more as a freelancer</a>, your existing clients will often not understand.</p>
<p><em>"Why,"</em> they ask, <em>"are you suddenly valuing your services so much higher for the same work?"</em></p>
<p>Even before you explain whatever your reasoning is, you're entering the conversation with them on the back foot – they're feeling an inkling of mistrust.</p>
<p>Potential new clients will simply turn away and look for another freelancer who can offer them the same service at a lower hourly rate.</p>
<p>If you think you can just earn more by working more, ask yourself:</p>
<p>Is that sustainable? If so, do it.</p>
<p>But know that there will come a point where there are simply not more hours in the day to get more work done.</p>
<p>The other thing to consider is what if you're ill for 2 weeks?</p>
<p>What if you want to go on vacation for another 2 weeks of the year?</p>
<p>That's a whole month you just earned $0.</p>
<p>Sure, if you're charging massive hourly rates and you can save and make up for this loss, that's perfectly fine, but for the majority of 'hourly-billers', this can be a major problem.</p>
<p>Now before we on, let's go over some advantages of hourly pricing first so you can still weigh your options.</p>
<h3 id="heading-being-paid-hourly-is-a-benefit-itself">Being paid hourly is a benefit itself</h3>
<p>The hourly wage rate has the advantage of paying an individual for the hours they work. If you work for 8 hours a day, for example, you will be paid for the entire 8 hours, and if you work overtime, you will be paid more and get additional income.</p>
<h3 id="heading-work-and-life-balance">Work and life balance</h3>
<p>Since you have a set amount of time to work in a day, you are able to maintain the balance between your work and life activities. Once the working hours are over, you're free to do anything and even jump on another project (if you can still manage your time).</p>
<h3 id="heading-long-term-projects-and-clients">Long-term projects and clients</h3>
<p>Rather than short, intermittent employment, hourly rates are better for long-term projects and clientele. Hourly billing also makes it simple to account for project variations and adjustments.</p>
<p>Transitioning from hourly billing to value pricing is tricky (but worth it) and takes time if you're used to an hourly-based approach.</p>
<p>It requires a change in thinking, but, once you realize how ineffective it is to trade your time for money, you will find your profitability increasing.</p>
<h2 id="heading-value-based-pricing">Value-Based Pricing</h2>
<p>The key takeaways about the difference between value-based and hourly-based pricing are these:</p>
<ul>
<li>In hourly-based pricing, you sell your time.</li>
<li>In <a target="_blank" href="https://studywebdevelopment.com/hourly-billing-vs-value-pricing.html">value-based pricing</a>, you sell results.</li>
<li>In hourly-based pricing, you ask what they want to be built.</li>
<li>In value-based pricing, you ask why they want something built.</li>
</ul>
<p>This makes all the difference and can be a real game-changer if you're switching from hourly-based pricing.</p>
<p>With the focus on results, there are a lot more advantages for you and the client.</p>
<p>When you and your client understand the "why" (the value gained), value-based price will make perfect sense.</p>
<p>Before we get into that, let's look at how value-based pricing works:</p>
<ol>
<li>Find the potential value of a project to a client over a year.</li>
<li>Base your price off of those returns.</li>
</ol>
<p><strong>Example:</strong></p>
<p>Let's say a business sells an average of ten 3D printers at an average of $2,000 each per month ($20k sales per month). Then, after calculating that, I could potentially increase sales by 30% month after month (based on experience or <a target="_blank" href="https://swd.hashnode.dev/why-every-frontend-developer-should-learn-cro">CRO knowledge</a>). This would equal an extra three sales per month (or $6,000).</p>
<p>Even if we work on just 2 extra sales per month, it adds up to an extra $48,000 per year in additional revenue just by the changes and improvements I will be doing.</p>
<p>Therefore, charging $5,000 once-off for the website to potentially increase sales by almost $50,000 in one year is a no-brainer.</p>
<p>Let's look into the advantages of this approach:</p>
<h3 id="heading-freedom-to-make-great-websites">Freedom To Make Great Websites</h3>
<p>You can focus on creating something great without worrying about going over the client's budget or counting every hour.</p>
<p>This means you're not tied with any hourly work, trying to get over a day being productive when you're not really in the right mind to do the project, but you have to do something productive because your time is being tracked. It's also a common thing these days that your screen is being tracked, too.</p>
<h3 id="heading-incentivized-learning">Incentivized Learning</h3>
<p>Not only does this approach encourage you to find the most optimal solution, but it also incentivizes you to stay up to date with the latest technologies and tools that make your workflow easier and more productive.</p>
<h3 id="heading-no-hidden-costs-for-the-client">No Hidden Costs for the Client</h3>
<p>Since you've agreed on the price upfront, you take on all the risk. This means the client will have no financial surprises down the line which helps facilitate trust. In other words, the client experiences less risk. And this often leads to fewer arguments.</p>
<h3 id="heading-work-with-clients-that-you-enjoy">Work with Clients That You Enjoy</h3>
<p>The nature of value-based pricing means that you will likely be earning significantly more. You can now start working with fewer clients and provide a much better service while earning the same or more than you did while using hourly-based pricing.</p>
<h3 id="heading-scope-creep-insurance">Scope Creep Insurance</h3>
<p>Once a project has been defined in terms of the business outcomes (for example, increased traffic, more sales) instead of deliverables (like change the font size of the navigation bar items, the password reset form needs ReCAPTCHA) it’s fairly easy to control scope. This is because business needs don’t change that often, and random requests from the client can be judged against the desired outcome.</p>
<p>The crucial factor with value-based pricing is this: It is up to you to make the business see your services as a necessary investment and not a cost.</p>
<p>You need to show them that you are the right person by explaining how both of you benefit from the <a target="_blank" href="https://www.freecodecamp.org/news/the-different-ways-to-charge-for-a-website/">pricing approach</a> you're taking.</p>
<p>Bring their focus to the importance of results and what value the project will bring them.</p>
<p>Ultimately, this approach takes a lot of trial and error but trust the process and your future self will be thanking you.</p>
<p>By basing your value-based price on the client’s perceived value of the project outcome instead of your estimated labor, you can set your fees significantly higher, deliver more effective results, increase client satisfaction, and more.</p>
<p>Win-win.</p>
<h3 id="heading-disadvantages-of-value-based-pricing">Disadvantages of Value-Based Pricing</h3>
<p>Well, there's only one, to be honest. That is the difference between you and your client.</p>
<p>It's not easy to communicate this pricing method because the value in your mind might be different from the value your client sees. There are even some instances where your client might feel that they didn't get the right result for the price they paid.</p>
<p>It might be challenging to apply this method at first, but you do get better the more you do it.</p>
<p><strong>Remember:</strong></p>
<p>You want <a target="_blank" href="https://www.freecodecamp.org/news/what-to-charge-as-a-freelance-developer-dont-be-the-cheapest/">to charge</a> for your head, not your hands.</p>
<p>Smarts, not labor.</p>
<p>Results, not deliverables.</p>
<p>Outcomes, not activities.</p>
<h2 id="heading-other-pricing-methods">Other Pricing Methods</h2>
<h3 id="heading-monthly-retainer">Monthly Retainer</h3>
<p>In a monthly retainer arrangement, the client pays you a set monthly price regardless of the quantity of work you complete in a month. </p>
<p>A lot of clients like retainers because they make budgeting easier for them. They know what they will get each month in exchange for a certain payment because the focus is on work and not hours.</p>
<h3 id="heading-fixed-fee">Fixed Fee</h3>
<p>A fixed-fee pricing strategy establishes a single price for all services. You can also create two or more fixed pricing options for your clients to choose from. There is a specified scope of work you will and will not complete.</p>
<h3 id="heading-performance-based-pricing">Performance-Based Pricing</h3>
<p>Performance-based pricing (also known as results-based pricing) is a sort of value-based pricing in which the price is determined by real performance measurements.</p>
<h2 id="heading-so-which-pricing-method-should-you-use">So, Which Pricing Method Should You Use?</h2>
<p>The method you choose is up to you and, for many people, hourly-based pricing works perfectly fine. But for me, it's value-based pricing.</p>
<p>If you do choose to switch to a value-based approach, remember that this new approach will take some getting used to but it will certainly be worth it in the long run.</p>
<p>Try experimenting on your own and combine a few methods to determine the right pricing for your <a target="_blank" href="https://studywebdevelopment.com/freelancing.html">freelancing services</a>.</p>
<p>I hope you found value from this article.</p>
<p>Until next time,</p>
<p>Kyle</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Static vs Dynamic Web Pages – What's the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ Imagine that you're interviewing for your dream job and the interviewer drops this question for you: “So can you distinguish between a static web page and a dynamic web page?” What would your reaction be? If you don’t know the answer to that question... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/static-vs-dynamic-web-pages/</link>
                <guid isPermaLink="false">66d4619a787a2a3b05af441a</guid>
                
                    <category>
                        <![CDATA[ interview questions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kingsley Ubah ]]>
                </dc:creator>
                <pubDate>Wed, 11 Aug 2021 19:54:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/staticdynamic.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Imagine that you're interviewing for your dream job and the interviewer drops this question for you:</p>
<p><em>“So can you distinguish between a static web page and a dynamic web page?”</em></p>
<p>What would your reaction be?</p>
<p>If you don’t know the answer to that question, or are struggling to think it up, then this article is for you.</p>
<p>If you're a beginner coder, you might have heard of the terms “static web pages” and “dynamic web pages” – but you might not know what they mean.</p>
<p>You might wonder what makes a web page static and what makes a web page dynamic.</p>
<p>In this article, I am going to tell you all you need to know – and why it's important. And, as usual, I will be doing so in plain English.</p>
<h2 id="heading-what-is-a-web-page">What is a Web Page?</h2>
<p>First, we need to understand what a web page and a web site are and how they differ. To do that, let’s consider an encyclopedia.</p>
<p>An encyclopedia (like Wikipedia, for example) consists of many pages. Each page has its own content: A header, paragraph, images, diagrams, bullet points, lists, and of course, the definitions of the terms you're looking up.</p>
<p>It is very common in an encyclopedia to find words on the page which refer (or link) to another page for additional information.</p>
<p>This is very similar to web pages and web sites.</p>
<p>A web page is a single document which can contain text, images, hypertext, or any other elements. We create web pages using a markup language such as HyperText Markup Language – more commonly known as HTML.</p>
<p>HyperText is any web document which contains hyperlinks. A hyperlink is any element in the web page which, when you click on it, links to another web page.</p>
<p>These interconnected web pages forms an organised network of web pages, which we then call a <strong>website</strong>.</p>
<p>Every web page accessible on the internet must have its own URL. Here’s a typical URL of a web page:</p>
<p><a target="_blank" href="http://www.freeCodeCamp.com/news"><code>www.freecodecamp.org/news</code></a></p>
<blockquote>
<p>N/B: In case you are wondering, the page that the above URL returns is a dynamic page. Don’t worry, we will find out what that means very shortly.</p>
</blockquote>
<p><strong>Now, I have a simple test for you:</strong></p>
<p>Open your web browser. Navigate to the address bar and type in (or select) any random but valid URL you know. Hit enter and wait. A web page will be rendered on your browser window. Take a snapshot of the current state of the web page and close it.</p>
<p>Wait for some time, and then visit that URL again. Then answer the following questions:</p>
<ul>
<li><p>If you compare the current state of the page to its previous state, are there any differences in its content?</p>
</li>
<li><p>Does the page’s URL ends with a document extension <code>/.html</code> for example) or did it end with an endpoint? <code>/profile</code> for example)</p>
</li>
<li><p>Assuming you change your browser settings (like clearing cookies, for example), does hitting the same URL returns a different page?</p>
</li>
<li><p>Are you prompted to submit a form before having the page rendered on your browser?</p>
</li>
</ul>
<p>How you answer these questions (and a couple more I will ask below) will determine whether the page is a static one or a dynamic one.</p>
<h2 id="heading-what-is-a-static-page">What is a Static Page?</h2>
<p>A static page has the following characteristics:</p>
<ul>
<li><p>The page is already present even before a user requests it. A static page must be already physically present and hydrated (i.e with content) by the time a user makes a request for it. If it is not present, then it is not static.</p>
</li>
<li><p>The page generally maintains the same content every time the user requests it. If hitting the same URL returns different content, then that page is not static at all. This is not to say static pages cannot be modified. But the only way to change a static page for the creator to manually edit the content (like an HTML document)</p>
</li>
</ul>
<p>Here's an example of a static page:</p>
<p><code>www.example.com/about.html</code></p>
<h2 id="heading-what-is-a-dynamic-page">What is a Dynamic Page?</h2>
<p>A dynamic page has the following characteristics:</p>
<ul>
<li><p>The page is not physically present on the server when the user makes a request for it</p>
</li>
<li><p>Instead, when a user makes a request a script or program runs and ultimately cooks up a web page. It does this by interacting with a database to retrieve data which it packages and sends over as a page.</p>
</li>
<li><p>On every request, every new page created may be different from the last.</p>
</li>
</ul>
<p>This is because the page created is dependent on the user's information and the program. The creator does not have to manually edit the content, as with Static Web Pages.</p>
<p>So, for example, if a different user requests the same page, different content is returned.</p>
<p>Or maybe when a user changes a setting, a new page is returned.</p>
<p>Or maybe when the time changes, different content is returned.</p>
<p>To illustrate this in a more intuitive way, let’s take a look at two scenarios in a Restaurant:</p>
<p><em>You are hungry, so you decide to go to a restaurant to eat. You order a plate of Jollof Rice (a Nigerian food). Through the transparent glass window into the kitchen, you can see that the food is already cooked. All the waiter has to do is to go over there, get the meal, and bring it to you.</em></p>
<p><em>Now let's say that you order a plate of suya (Nigerian meat). Typically, the meat is not already available and has to be prepared for you on the spot. With the information you supply to the waiter (your budget, how many onions you want, etc) the cook puts together your portion for you.</em></p>
<p>The first scenario illustrates how a static page is rendered. The second scenario illustrates how a dynamic page is rendered.</p>
<p>Here's an example of a dynamic page:</p>
<p><code>www.example.com/courses</code></p>
<p>The /course URL is not a document extension, but rather it's an <strong>endpoint</strong>.</p>
<p>Making requests to that endpoint will trigger a program which will use the supplied user data (such as username and password) and probably some external variables (such as the time and date) to interact with database and ultimately create and return a newly formed web page.</p>
<p>This is also why I earlier said that freeCodeCamp's news page is dynamic – because the content changes as new articles are published.</p>
<p>That page never existed as a file on the server. Instead, it was created by the script that ran when the user requested it.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>A web page is a single document which contains text, images, hypertext and other elements.</p>
<p>A hypertext is a web document which contains hyperlinks. A hyperlink links one web page with another.</p>
<p>A network of organized webpages that link to each other is called a website.</p>
<p>For a website to be considered static, every call to the same URL returns the same web page.</p>
<p>One the other hand, if the content changes a lot, then that web page is dynamic. A dynamic page also ends with an endpoint, not a filepath.</p>
<p>So that's it. Hopefully now you can distinguish between a static web page and a dynamic web page. I really hope you got something useful from this article.</p>
<p>If you want more, I recently started a <strong>weekly coding challenge series</strong> aimed at teaching beginners how to program in JavaScript. Check it out on <a target="_blank" href="https://ubahthebuilder.tech/day-1-who-likes-it">my blog</a>.</p>
<p>Thank you for reading and see you soon.</p>
<blockquote>
<p><strong>P/S</strong>: If you are learning JavaScript, I created an eBook which teaches 50 topics in JavaScript with hand-drawn digital notes. <a target="_blank" href="https://ubahthebuilder.gumroad.com/l/js-50">Check it out here</a>.</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Keep a Historical Record of Lighthouse Reports ]]>
                </title>
                <description>
                    <![CDATA[ By Adam Henson Lighthouse is an open-source project from the Google Chrome team. It's used to analyze web page quality based on a set of modern, "user-centric" metrics.  When supporting websites that rely on organic search results for revenue, qualit... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-keep-a-historical-record-of-lighthouse-reports/</link>
                <guid isPermaLink="false">66d45d599208fb118cc6cf83</guid>
                
                    <category>
                        <![CDATA[ Lighthouse ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SEO ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 28 May 2020 13:02:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/lighthouse-logo-in-water-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adam Henson</p>
<p>Lighthouse is an open-source project from the Google Chrome team. It's used to analyze web page quality based on a set of modern, "user-centric" metrics. </p>
<p>When supporting websites that rely on organic search results for revenue, quality is critical. Performance, accessibility and general SEO best practices are major factors in search engine rankings. </p>
<p>Lighthouse provides a granular set of metrics that represent these factors and suggestions of improvement in reporting. </p>
<p>There are <a target="_blank" href="https://developers.google.com/web/tools/lighthouse">many ways of running Lighthouse</a>, but in the real world you may want to compare reports regularly, especially in continuous change workflows. With that said, you might be wondering - <strong>how can I keep track of SEO, performance, and accessibility changes over time</strong>?</p>
<p>This post covers how to use <a target="_blank" href="https://www.foo.software/lighthouse">Automated Lighthouse Check</a> to analyze website quality over time. But keep in mind that there are many other <a target="_blank" href="https://github.com/GoogleChrome/lighthouse#lighthouse-integrations">Lighthouse integrations</a> to choose from.</p>
<h2 id="heading-saving-reports-and-viewing-results-in-a-timeline">Saving Reports and Viewing Results in a Timeline</h2>
<p><a target="_blank" href="https://developers.google.com/web/tools/lighthouse/v3/scoring">Lighthouse scoring</a> is an interesting aspect of the tool that may feel a little dirty at first. Still, it can be a very useful point of comparison when looking at historical data. </p>
<p>The performance category in particular is quite complicated in its calculation of score and you can find a lot of <a target="_blank" href="https://web.dev/performance-scoring/">great reading about the topic among others on web.dev</a>.</p>
<p>Automated Lighthouse Check provides a means of manually triggering audits or establishing a schedule in which they run automatically throughout the day. These audits are saved in a database so you can visualize and analyze results at a historical level. You can actually drill into any report in time to see full details (<a target="_blank" href="https://www.foo.software/dashboard/page/5d1d459641e33a002f256efc">see an example here</a>).</p>
<p>For a guide to getting started with Automated Lighthouse Check, <a target="_blank" href="https://www.foo.software/automated-lighthouse-check-getting-started/">see the documentation</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/automated-ligthouse-check-timeline.png" alt="Image" width="600" height="400" loading="lazy">
<em>Timeline view of Lighthouse scores</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screen-Shot-2020-05-28-at-8.15.32-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>A historical list of Lighthouse audits</em></p>
<h2 id="heading-lighthouse-automation-in-devops">Lighthouse Automation in DevOps</h2>
<p>Not only are there many useful cloud-based Lighthouse tools, but there are also many open-source projects that can be implemented in a variety of DevOps workflows. Some of these solutions support persistence of data in one form or another, to track historically. </p>
<p>Below are a few examples that I've contributed to.</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-lighthouse-in-circleci/">This post covers how to use Lighthouse in CircleCI</a>. You can save reports as "artifacts" in CircleCI or upload to AWS S3 automatically.</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-lighthouse-in-github-actions/">This post covers how to use Lighthouse in GitHub Actions</a>. This solution also provides a way to save reports as "artifacts" (in GitHub) or upload to AWS S3 automatically.</li>
<li><a target="_blank" href="https://www.npmjs.com/package/@foo-software/lighthouse-persist">Lighthouse Persist is an NPM package</a> that exposes the native Lighthouse API with additional options to set AWS S3 credentials so it can be used to upload reports automatically.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screen-Shot-2020-05-28-at-8.34.59-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>A few friends - Octocat, Jenkins, CircleCI</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope this post was helpful in providing solutions for analyzing website quality historically. Help support your local developers by purchasing their software ?</p>
<p>But in all seriousness, I'd love any feedback about Automated Lighthouse Check... comments, suggestions, feature requests, etc. It's about a year old at the time of this writing and has recently been migrated to Kubernetes for high availability. </p>
<p>Automated Lighthouse Check provides <a target="_blank" href="https://www.foo.software/pricing">free and premium plans</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Hugo vs Jekyll: an Epic Battle of Static Site Generator Themes ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we'll compare the nuances of creating themes for the top two static site generators. I recently took on the task of creating a documentation site theme for two projects. Both projects needed the same basic features, but one uses Jeky... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/hugo-vs-jekyll-battle-of-static-site-generator-themes/</link>
                <guid isPermaLink="false">66bd8f5f27629f4c5e1893b2</guid>
                
                    <category>
                        <![CDATA[ Hugo ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JAMstack ]]>
                    </category>
                
                    <category>
                        <![CDATA[ jekyll ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Static Site Generators ]]>
                    </category>
                
                    <category>
                        <![CDATA[ themes ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Mon, 27 Apr 2020 13:42:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/cover-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we'll compare the nuances of creating themes for the top two static site generators.</p>
<p>I recently took on the task of creating a documentation site theme for two projects. Both projects needed the same basic features, but one uses Jekyll while the other uses Hugo.</p>
<p>In typical developer rationality, there was clearly only one option. I decided to create the same theme in both frameworks, and to give you, dear reader, a side-by-side comparison.</p>
<p>This post isn’t a comprehensive theme-building guide, but is rather intended to familiarize you with the process of building a theme in either generator. Here's what we'll cover:</p>
<ul>
<li>How theme files are organized</li>
<li>Where to put content</li>
<li>How templating works</li>
<li>Creating a top-level menu with the <code>pages</code> object</li>
<li>Creating a menu with nested links from a data list</li>
<li>Putting the template together</li>
<li>Creating styles</li>
<li>How to configure and deploy to GitHub Pages</li>
</ul>
<p>Here’s a crappy wireframe of the theme I’m going to create.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/wireframe.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you’re planning to build-along, it may be helpful to serve the theme locally as you build it – and both generators offer this functionality. For Jekyll, run <code>jekyll serve</code>, and for Hugo, <code>hugo serve</code>.</p>
<p>There are two main elements: the main content area, and the all-important sidebar menu. To create them, you’ll need template files that tell the site generator how to generate the HTML page. To organize theme template files in a sensible way, you first need to know what  directory structure the site generator expects.</p>
<h2 id="heading-how-theme-files-are-organized">How theme files are organized</h2>
<p>Jekyll supports gem-based themes, which users can install like any other Ruby gems. This method hides theme files in the gem, so for the purposes of this comparison, we aren’t using gem-based themes.</p>
<p>When you run <code>jekyll new-theme &lt;name&gt;</code>, Jekyll will scaffold a new theme for you. Here’s what those files look like:</p>
<pre><code class="lang-sh">.
├── assets
├── Gemfile
├── _includes
├── _layouts
│   ├── default.html
│   ├── page.html
│   └── post.html
├── LICENSE.txt
├── README.md
├── _sass
└── &lt;name&gt;.gemspec
</code></pre>
<p>The directory names are appropriately descriptive. The <code>_includes</code> directory is for small bits of code that you reuse in different places,  in much the same way you’d put butter on everything. (Just me?) </p>
<p>The <code>_layouts</code> directory contains templates for different types of pages on your site. The <code>_sass</code> folder is for <a target="_blank" href="https://sass-lang.com/documentation/syntax">Sass</a> files used to build your site’s stylesheet.</p>
<p>You can scaffold a new Hugo theme by running <code>hugo new theme &lt;name&gt;</code>. It has these files:</p>
<pre><code class="lang-sh">.
├── archetypes
│   └── default.md
├── layouts
│   ├── 404.html
│   ├── _default
│   │   ├── baseof.html
│   │   ├── list.html
│   │   └── single.html
│   ├── index.html
│   └── partials
│       ├── footer.html
│       ├── header.html
│       └── head.html
├── LICENSE
├── static
│   ├── css
│   └── js
└── theme.toml
</code></pre>
<p>You can see some similarities. Hugo’s page template files are tucked into <code>layouts/</code>. Note that the <code>_default</code> page type has files for a <code>list.html</code> and a <code>single.html</code>. </p>
<p>Unlike Jekyll, Hugo uses these specific file names to distinguish between <a target="_blank" href="https://gohugo.io/templates/lists/">list pages</a> (like a page with links to all your blog posts on it) and <a target="_blank" href="https://gohugo.io/templates/single-page-templates/">single pages</a> (like one of your blog posts). The <code>layouts/partials/</code> directory contains the buttery reusable bits, and stylesheet files have a spot picked out in <code>static/css/</code>.</p>
<p>These directory structures aren’t set in stone, as both site generators allow some measure of customization. For example, Jekyll lets  you define <a target="_blank" href="https://jekyllrb.com/docs/collections/">collections</a>, and Hugo makes use of <a target="_blank" href="https://gohugo.io/content-management/page-bundles/">page bundles</a>. These features let you organize your content multiple ways, but for now, let's look at where to put some simple pages.</p>
<h2 id="heading-where-to-put-content">Where to put content</h2>
<p>To create a site menu that looks like this:</p>
<pre><code class="lang-md">Introduction
<span class="hljs-code">    Getting Started
    Configuration
    Deploying
Advanced Usage
    All Configuration Settings
    Customizing
    Help and Support</span>
</code></pre>
<p>You’ll need two sections (“Introduction” and “Advanced Usage”) containing their respective subsections.</p>
<p>Jekyll isn’t strict with its content location. It expects pages in the root of your site, and will build whatever’s there. Here’s how you might organize these pages in your Jekyll site root:</p>
<pre><code class="lang-sh">.
├── 404.html
├── assets
├── Gemfile
├── _includes
├── index.markdown
├── intro
│   ├── config.md
│   ├── deploy.md
│   ├── index.md
│   └── quickstart.md
├── _layouts
│   ├── default.html
│   ├── page.html
│   └── post.html
├── LICENSE.txt
├── README.md
├── _sass
├── &lt;name&gt;.gemspec
└── usage
    ├── customizing.md
    ├── index.md
    ├── settings.md
    └── support.md
</code></pre>
<p>You can change the location of the site source in your <a target="_blank" href="https://jekyllrb.com/docs/configuration/default/">Jekyll configuration</a>.</p>
<p>In Hugo, all rendered content is expected in the <code>content/</code> folder. This prevents Hugo from trying to render pages you don’t want, such as <code>404.html</code>, as site content. Here’s how you might organize your <code>content/</code> directory in Hugo:</p>
<pre><code class="lang-sh">.
├── _index.md
├── intro
│   ├── config.md
│   ├── deploy.md
│   ├── _index.md
│   └── quickstart.md
└── usage
    ├── customizing.md
    ├── _index.md
    ├── settings.md
    └── support.md
</code></pre>
<p>To Hugo, <code>_index.md</code> and <code>index.md</code> mean different things. It can be helpful to know what kind of <a target="_blank" href="https://gohugo.io/content-management/page-bundles/">Page Bundle</a> you want for each section: Leaf, which has no children, or Branch.</p>
<p>Now that you have some idea of where to put things, let’s look at how to build a page template.</p>
<h2 id="heading-how-templating-works">How templating works</h2>
<p>Jekyll page templates are built with the <a target="_blank" href="https://jekyllrb.com/docs/liquid/">Liquid templating language</a>. It uses braces to output variable content to a page, such as the page’s title: <code>{{ page.title }}</code>.</p>
<p>Hugo’s templates also use braces, but they’re built with <a target="_blank" href="https://gohugo.io/templates/introduction/">Go Templates</a>. The syntax is similar, but different: <code>{{ .Title }}</code>.</p>
<p>Both Liquid and Go Templates can handle logic. Liquid uses <em>tags</em> syntax to denote logic operations:</p>
<pre><code class="lang-liquid">{% if user %}
  Hello {{ user.name }}!
{% endif %}
</code></pre>
<p>And Go Templates places its functions and arguments in its braces syntax:</p>
<pre><code class="lang-go">{{ <span class="hljs-keyword">if</span> .User }}
    Hello {{ .User }}!
{{ end }}
</code></pre>
<p>Templating languages allow you to build one  skeleton HTML page, then tell the site generator to put variable content in areas you define. Let’s compare two possible <code>default</code> page templates for Jekyll and Hugo.</p>
<p>Jekyll’s scaffold <code>default</code> theme is bare, so we’ll look at their starter theme <a target="_blank" href="https://github.com/jekyll/minima">Minima</a>. Here’s <code>_layouts/default.html</code> in Jekyll (Liquid):</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"{{ page.lang | default: site.lang | default: "</span><span class="hljs-attr">en</span>" }}"&gt;</span>

  {%- include head.html -%}

  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>

    {%- include header.html -%}

    <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"page-content"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Content"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"wrapper"</span>&gt;</span>
        {{ content }}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>

    {%- include footer.html -%}

  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Here’s Hugo’s scaffold theme <code>layouts/_default/baseof.html</code> (Go Templates):</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    {{- partial "head.html" . -}}
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        {{- partial "header.html" . -}}
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span>&gt;</span>
        {{- block "main" . }}{{- end }}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        {{- partial "footer.html" . -}}
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Different syntax, same idea. Both templates pull in reusable bits for <code>head.html</code>, <code>header.html</code>, and <code>footer.html</code>.  These show up on a lot of pages, so it makes sense not to have to  repeat yourself. </p>
<p>Both templates also have a spot for the main content, though the Jekyll template uses a variable (<code>{{ content }}</code>) while Hugo uses a block (<code>{{- block "main" . }}{{- end }}</code>). <a target="_blank" href="https://gohugo.io/templates/base/#readout">Blocks</a> are just another way Hugo lets you define reusable bits.</p>
<p>Now that you know how templating works, you can build the sidebar menu for the theme.</p>
<h2 id="heading-creating-a-top-level-menu-with-the-pages-object">Creating a top-level menu with the <code>pages</code> object</h2>
<p>You can programmatically create a top-level menu from your pages. It will look like this:</p>
<pre><code class="lang-md">Introduction
Advanced Usage
</code></pre>
<p>Let’s start with Jekyll. You can display links to site pages in your Liquid template by iterating through the <code>site.pages</code> object that Jekyll provides and building a list:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    {% for page in site.pages %}
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ page.url | absolute_url }}"</span>&gt;</span>{{ page.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    {% endfor %}
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>This returns all of the site’s pages, including all the ones that you might not want, like <code>404.html</code>. You can filter for the pages you actually want with a couple more tags, such as conditionally including pages if they have a <code>section: true</code> parameter set:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    {% for page in site.pages %}
    {%- if page.section -%}
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ page.url | absolute_url }}"</span>&gt;</span>{{ page.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    {%- endif -%}
    {% endfor %}
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>You can achieve the same effect with slightly less code in Hugo. Loop through Hugo’s <code>.Pages</code> object using Go Template’s <a target="_blank" href="https://golang.org/pkg/text/template/#hdr-Actions"><code>range</code> action</a>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
{{ range .Pages }}
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{.Permalink}}"</span>&gt;</span>{{.Title}}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
{{ end }}
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>This template uses the <code>.Pages</code> object to return all the top-level pages in <code>content/</code> of your Hugo site. Since Hugo uses a specific folder for the site content you want rendered, there’s no additional filtering necessary to build a simple menu of site pages.</p>
<h2 id="heading-creating-a-menu-with-nested-links-from-a-data-list">Creating a menu with nested links from a data list</h2>
<p>Both site generators can use a separately defined data list of links to render a menu in your template. This is more suitable for creating nested links, like this:</p>
<pre><code class="lang-md">Introduction
<span class="hljs-code">    Getting Started
    Configuration
    Deploying
Advanced Usage
    All Configuration Settings
    Customizing
    Help and Support</span>
</code></pre>
<p>Jekyll supports <a target="_blank" href="https://jekyllrb.com/docs/datafiles/">data files</a> in a few formats, including YAML. Here’s the definition for the menu above in <code>_data/menu.yml</code>:</p>
<pre><code class="lang-yml"><span class="hljs-attr">section:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">page:</span> <span class="hljs-string">Introduction</span>
    <span class="hljs-attr">url:</span> <span class="hljs-string">/intro</span>
    <span class="hljs-attr">subsection:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">page:</span> <span class="hljs-string">Getting</span> <span class="hljs-string">Started</span>
        <span class="hljs-attr">url:</span> <span class="hljs-string">/intro/quickstart</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">page:</span> <span class="hljs-string">Configuration</span>
        <span class="hljs-attr">url:</span> <span class="hljs-string">/intro/config</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">page:</span> <span class="hljs-string">Deploying</span>
        <span class="hljs-attr">url:</span> <span class="hljs-string">/intro/deploy</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">page:</span> <span class="hljs-string">Advanced</span> <span class="hljs-string">Usage</span>
    <span class="hljs-attr">url:</span> <span class="hljs-string">/usage</span>
    <span class="hljs-attr">subsection:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">page:</span> <span class="hljs-string">Customizing</span>
        <span class="hljs-attr">url:</span> <span class="hljs-string">/usage/customizing</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">page:</span> <span class="hljs-string">All</span> <span class="hljs-string">Configuration</span> <span class="hljs-string">Settings</span>
        <span class="hljs-attr">url:</span> <span class="hljs-string">/usage/settings</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">page:</span> <span class="hljs-string">Help</span> <span class="hljs-string">and</span> <span class="hljs-string">Support</span>
        <span class="hljs-attr">url:</span> <span class="hljs-string">/usage/support</span>
</code></pre>
<p>Here’s how to render the data in the sidebar template:</p>
<pre><code class="lang-html">{% for a in site.data.menu.section %}
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ a.url }}"</span>&gt;</span>{{ a.page }}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    {% for b in a.subsection %}
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ b.url }}"</span>&gt;</span>{{ b.page }}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    {% endfor %}
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
{% endfor %}
</code></pre>
<p>This method allows you to build a custom menu, two nesting levels deep. The nesting levels are limited by the <code>for</code> loops in the template. For a recursive version that handles further levels of nesting, see <a target="_blank" href="https://jekyllrb.com/tutorials/navigation/#scenario-9-nested-tree-navigation-with-recursion">Nested tree navigation with recursion</a>.</p>
<p>Hugo does something similar with its <a target="_blank" href="https://gohugo.io/templates/menu-templates/#section-menu-for-lazy-bloggers">menu templates</a>. You can define menu links in your <a target="_blank" href="https://gohugo.io/getting-started/configuration/">Hugo site config</a>, and even add useful properties that Hugo understands, like weighting. Here’s a definition of the menu above in <code>config.yaml</code>:</p>
<pre><code class="lang-yml"><span class="hljs-attr">sectionPagesMenu:</span> <span class="hljs-string">main</span>

<span class="hljs-attr">menu:</span>  
  <span class="hljs-attr">main:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">identifier:</span> <span class="hljs-string">intro</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">Introduction</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/intro/</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">1</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Getting</span> <span class="hljs-string">Started</span>
      <span class="hljs-attr">parent:</span> <span class="hljs-string">intro</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/intro/quickstart/</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">1</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Configuration</span>
      <span class="hljs-attr">parent:</span> <span class="hljs-string">intro</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/intro/config/</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">2</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Deploying</span>
      <span class="hljs-attr">parent:</span> <span class="hljs-string">intro</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/intro/deploy/</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">3</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">identifier:</span> <span class="hljs-string">usage</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">Advanced</span> <span class="hljs-string">Usage</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/usage/</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Customizing</span>
      <span class="hljs-attr">parent:</span> <span class="hljs-string">usage</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/usage/customizing/</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">2</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">All</span> <span class="hljs-string">Configuration</span> <span class="hljs-string">Settings</span>
      <span class="hljs-attr">parent:</span> <span class="hljs-string">usage</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/usage/settings/</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">1</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Help</span> <span class="hljs-string">and</span> <span class="hljs-string">Support</span>
      <span class="hljs-attr">parent:</span> <span class="hljs-string">usage</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/usage/support/</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">3</span>
</code></pre>
<p>Hugo uses the <code>identifier</code>, which must match the section name, along with the <code>parent</code> variable to handle nesting. Here’s how to render the menu in the sidebar template:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    {{ range .Site.Menus.main }}
    {{ if .HasChildren }}
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ .URL }}"</span>&gt;</span>{{ .Name }}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"sub-menu"</span>&gt;</span>
        {{ range .Children }}
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ .URL }}"</span>&gt;</span>{{ .Name }}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        {{ end }}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    {{ else }}
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ .URL }}"</span>&gt;</span>{{ .Name }}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    {{ end }}
    {{ end }}
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>The <code>range</code> function iterates over the menu data, and Hugo’s <code>.Children</code> variable handles nested pages for you.</p>
<h2 id="heading-putting-the-template-together">Putting the template together</h2>
<p>With your menu in your reusable sidebar bit (<code>_includes/sidebar.html</code> for Jekyll and <code>partials/sidebar.html</code> for Hugo), you can add it to the <code>default.html</code> template.</p>
<p>In Jekyll:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"{{ page.lang | default: site.lang | default: "</span><span class="hljs-attr">en</span>" }}"&gt;</span>

{%- include head.html -%}

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    {%- include sidebar.html -%}

    {%- include header.html -%}

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"page-content"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Content"</span>&gt;</span>
        {{ content }}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    {%- include footer.html -%}

<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In Hugo:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
{{- partial "head.html" . -}}

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    {{- partial "sidebar.html" . -}}

    {{- partial "header.html" . -}}
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"page-content"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Content"</span>&gt;</span>
        {{- block "main" . }}{{- end }}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    {{- partial "footer.html" . -}}
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>When the site is generated, each page will contain all the code from your <code>sidebar.html</code>.</p>
<h2 id="heading-create-a-stylesheet">Create a stylesheet</h2>
<p>Both site generators accept Sass for creating CSS stylesheets. Jekyll <a target="_blank" href="https://jekyllrb.com/docs/assets/">has Sass processing built in</a>, and Hugo uses <a target="_blank" href="https://gohugo.io/hugo-pipes/scss-sass/">Hugo Pipes</a>. Both options have some quirks.</p>
<h3 id="heading-sass-and-css-in-jekyll">Sass and CSS in Jekyll</h3>
<p>To process a Sass file in Jekyll, create your style definitions in the <code>_sass</code> directory. For example, in a file at <code>_sass/style-definitions.scss</code>:</p>
<pre><code class="lang-scss"><span class="hljs-variable">$background-color</span>: <span class="hljs-number">#eef</span> !default;
<span class="hljs-variable">$text-color</span>: <span class="hljs-number">#111</span> !default;

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-variable">$background-color</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-variable">$text-color</span>;
}
</code></pre>
<p>Jekyll won’t generate this file directly, as it only processes files with front matter. To create the end-result  filepath for your site’s stylesheet, use a placeholder with empty front matter where you want the <code>.css</code> file to appear. For example, <code>assets/css/style.scss</code>. In this file, simply import your styles:</p>
<pre><code class="lang-scss">---
---

<span class="hljs-keyword">@import</span> <span class="hljs-string">"style-definitions"</span>;
</code></pre>
<p>This rather hackish configuration has an upside: you can use Liquid template tags and variables in your placeholder file. This is a nice way to allow users to set variables from the site <code>_config.yml</code>, for example.</p>
<p>The resulting CSS stylesheet in your generated site has the path <code>/assets/css/style.css</code>. You can link to it in your site’s <code>head.html</code> using:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ "</span>/<span class="hljs-attr">assets</span>/<span class="hljs-attr">css</span>/<span class="hljs-attr">style.css</span>" | <span class="hljs-attr">relative_url</span> }}" <span class="hljs-attr">media</span>=<span class="hljs-string">"screen"</span>&gt;</span>
</code></pre>
<h3 id="heading-sass-and-hugo-pipes-in-hugo">Sass and Hugo Pipes in Hugo</h3>
<p>Hugo uses <a target="_blank" href="https://gohugo.io/hugo-pipes/scss-sass/">Hugo Pipes</a> to process Sass to CSS. You can achieve this by using Hugo’s asset processing function, <code>resources.ToCSS</code>, which expects a source in the <code>assets/</code> directory. It takes the SCSS file as an argument. </p>
<p>With your style definitions in a Sass file at <code>assets/sass/style.scss</code>, here’s how to get, process, and link your Sass in your theme’s <code>head.html</code>:</p>
<pre><code class="lang-html">{{ $style := resources.Get "/sass/style.scss" | resources.ToCSS }}
<span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ $style.RelPermalink }}"</span> <span class="hljs-attr">media</span>=<span class="hljs-string">"screen"</span>&gt;</span>
</code></pre>
<p>Hugo asset processing <a target="_blank" href="https://gohugo.io/troubleshooting/faq/#i-get-tocss--this-feature-is-not-available-in-your-current-hugo-version">requires extended Hugo</a>, which you may not have by default. You can get extended Hugo from the <a target="_blank" href="https://github.com/gohugoio/hugo/releases">releases page</a>.</p>
<h2 id="heading-configure-and-deploy-to-github-pages">Configure and deploy to GitHub Pages</h2>
<p>Before your site generator can build your site, it needs a  configuration file to set some necessary parameters. Configuration files  live in the site root directory. Among other settings, you can declare  the name of the theme to use when building the site.</p>
<h3 id="heading-configure-jekyll">Configure Jekyll</h3>
<p>Here’s a minimal <code>_config.yml</code> for Jekyll:</p>
<pre><code class="lang-yml"><span class="hljs-attr">title:</span> <span class="hljs-string">Your</span> <span class="hljs-string">awesome</span> <span class="hljs-string">title</span>
<span class="hljs-attr">description:</span> <span class="hljs-string">&gt;-</span> <span class="hljs-comment"># this means to ignore newlines until "baseurl:"</span>
  <span class="hljs-string">Write</span> <span class="hljs-string">an</span> <span class="hljs-string">awesome</span> <span class="hljs-string">description</span> <span class="hljs-string">for</span> <span class="hljs-string">your</span> <span class="hljs-string">new</span> <span class="hljs-string">site</span> <span class="hljs-string">here.</span> <span class="hljs-string">You</span> <span class="hljs-string">can</span> <span class="hljs-string">edit</span> <span class="hljs-string">this</span>
  <span class="hljs-string">line</span> <span class="hljs-string">in</span> <span class="hljs-string">_config.yml.</span> <span class="hljs-string">It</span> <span class="hljs-string">will</span> <span class="hljs-string">appear</span> <span class="hljs-string">in</span> <span class="hljs-string">your</span> <span class="hljs-string">document</span> <span class="hljs-string">head</span> <span class="hljs-string">meta</span> <span class="hljs-string">(for</span>
  <span class="hljs-string">Google</span> <span class="hljs-string">search</span> <span class="hljs-string">results)</span> <span class="hljs-string">and</span> <span class="hljs-string">in</span> <span class="hljs-string">your</span> <span class="hljs-string">feed.xml</span> <span class="hljs-string">site</span> <span class="hljs-string">description.</span>
<span class="hljs-attr">baseurl:</span> <span class="hljs-string">""</span> <span class="hljs-comment"># the subpath of your site, e.g. /blog</span>
<span class="hljs-attr">url:</span> <span class="hljs-string">""</span> <span class="hljs-comment"># the base hostname &amp; protocol for your site, e.g. http://example.com</span>
<span class="hljs-attr">theme:</span> <span class="hljs-comment"># for gem-based themes</span>
<span class="hljs-attr">remote_theme:</span> <span class="hljs-comment"># for themes hosted on GitHub, when used with GitHub Pages</span>
</code></pre>
<p>With <code>remote_theme</code>, any <a target="_blank" href="https://help.github.com/en/github/working-with-github-pages/adding-a-theme-to-your-github-pages-site-using-jekyll#adding-a-jekyll-theme-in-your-sites-_configyml-file">Jekyll theme hosted on GitHub can be used</a> with sites hosted on GitHub Pages.</p>
<p>Jekyll has a <a target="_blank" href="https://jekyllrb.com/docs/configuration/default/">default configuration</a>, so any parameters added to your configuration file will override the defaults. Here are <a target="_blank" href="https://jekyllrb.com/docs/configuration/options/">additional configuration settings</a>.</p>
<h3 id="heading-configure-hugo">Configure Hugo</h3>
<p>Here’s a minimal example of Hugo’s <code>config.yml</code>:</p>
<pre><code class="lang-yml"><span class="hljs-attr">baseURL:</span> <span class="hljs-string">https://example.com/</span> <span class="hljs-comment"># The full domain your site will live at</span>
<span class="hljs-attr">languageCode:</span> <span class="hljs-string">en-us</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">Hugo</span> <span class="hljs-string">Docs</span> <span class="hljs-string">Site</span>
<span class="hljs-attr">theme:</span> <span class="hljs-comment"># theme name</span>
</code></pre>
<p>Hugo makes no assumptions, so if a necessary parameter is missing, you’ll see a warning when building or serving your site. Here are <a target="_blank" href="https://gohugo.io/getting-started/configuration/#all-configuration-settings">all configuration settings for Hugo</a>.</p>
<h3 id="heading-deploy-to-github-pages">Deploy to GitHub Pages</h3>
<p>Both generators build your site with a command.</p>
<p>For Jekyll, use <code>jekyll build</code>. See <a target="_blank" href="https://jekyllrb.com/docs/configuration/options/#build-command-options">further build options here</a>.</p>
<p>For Hugo, use <code>hugo</code>. You can run <code>hugo help</code> or see <a target="_blank" href="https://gohugo.io/getting-started/usage/#test-installation">further build options here</a>.</p>
<p>You’ll have to choose the source for your GitHub Pages site. Once done, your site will update each time you push a new build. Of course, you can also automate your GitHub Pages build using GitHub Actions. Here’s one for <a target="_blank" href="https://github.com/victoriadrake/hugo-latest-cd">building and deploying with Hugo</a>, and one for <a target="_blank" href="https://github.com/victoriadrake/jekyll-cd">building and deploying Jekyll</a>.</p>
<h2 id="heading-showtime">Showtime!</h2>
<p>All the substantial differences between these two generators are under the hood. All the same, let’s take a look at the finished themes, in two color variations.</p>
<p>Here’s Hugo:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/ogd_hugo.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here's Jekyll:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/ogd_jekyll.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-wait-who-won">Wait who won?</h2>
<p>?</p>
<p>Both Hugo and Jekyll have their quirks and conveniences.</p>
<p>From this developer’s perspective, Jekyll is a workable choice for simple sites without complicated organizational needs. If you’re looking to render some one-page posts in an <a target="_blank" href="https://jekyllrb.com/docs/themes/">available theme</a> and host with GitHub Pages, Jekyll will get you up and running fairly quickly.</p>
<p>Personally, I use Hugo. I like the organizational capabilities of its Page Bundles, and it’s backed by a dedicated and conscientious team that really seems to strive to facilitate convenience for their users. This is evident in Hugo’s many functions, and handy tricks like <a target="_blank" href="https://gohugo.io/content-management/image-processing/">Image Processing</a> and <a target="_blank" href="https://gohugo.io/content-management/shortcodes/">Shortcodes</a>. They seem to release new fixes and versions about as often as I make a new cup of coffee - which, depending on your use case, may be fantastic, or annoying.</p>
<p>If you still can’t decide, don’t worry. The <a target="_blank" href="https://github.com/opengitdocs">OpenGitDocs documentation theme</a> I created is available for both Hugo and Jekyll. Start with one, switch later if you want. That’s the benefit of having options.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Ultimate Node.js Production Checklist ]]>
                </title>
                <description>
                    <![CDATA[ By Mehul Mohan Are you doing this Node thing right on production? Let's see some common mistakes people make running Node on production (coming straight from my own projects - like codedamn) and how they can be mitigated.  You can use this as your ch... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/node-js-production-checklist/</link>
                <guid isPermaLink="false">66d4606e3a8352b6c5a2aac0</guid>
                
                    <category>
                        <![CDATA[ node ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ servers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 24 Mar 2020 11:32:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/screely-1585049597841.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Mehul Mohan</p>
<p>Are you doing this Node thing right on production? Let's see some common mistakes people make running Node on production (coming straight from my own projects - like <a target="_blank" href="https://codedamn.com">codedamn</a>) and how they can be mitigated. </p>
<p>You can use this as your checklist on production when you're deploying Node apps. Since this is a <em>production-ready-practices</em> article, a lot of them won't apply when you're developing apps on your local system.</p>
<h2 id="heading-run-node-in-cluster-modeseparate-node-processes">Run node in cluster mode/separate node processes</h2>
<p>Remember that Node is single threaded. It can delegate a lot of things (like HTTP requests and filesystem read/writes) to the OS which handles it in a multithreaded environment. But still, the code YOU write, the application logic, always runs in a single thread. </p>
<p>By running in a single thread, your Node process is always limited to only a single core on your machine. So if you have a server with multiple cores, you're wasting computation power running Node just once on your server.</p>
<p>What does "running Node just once" mean? You see, operating systems have a scheduler built into them which is responsible for how the execution of processes is distributed across the CPUs of the machine. When you run only 2 processes on a 2-core machine, the OS determines it is best to run both of the processes on separate cores to squeeze out maximum performance.</p>
<p>A similar thing needs to be done with Node. You have two options at this point:</p>
<ol>
<li><strong>Run Node in cluster mode -</strong> Cluster mode is an architecture which comes baked into Node itself. In simple words, Node forks more processes of its own and distributes load through a single master process.</li>
<li><strong>Run Node processes independently -</strong> This option is slightly different from the above in the sense that you now do not have a master process controlling the child Node processes. This means that when you spawn different Node processes, they'll run completely independent of each other. No shared memory, no IPC, no communication, nada.</li>
</ol>
<p>According to a <a target="_blank" href="https://stackoverflow.com/a/47122606/2513722">stackoverflow answer</a>, the latter (point 2) performs far better than the former (point 1) but is a little tricker to setup. </p>
<p>Why? Because in a Node app, not only is there application logic, but almost always when you're setting up servers in Node code you need to bind ports. And a single application codebase cannot bind the same port twice on the same OS. </p>
<p>This problem is, however, easily fixable. Environment variables, Docker containers, NGiNX frontend proxy, and so on are some of the solutions for this.</p>
<h2 id="heading-rate-limiting-your-endpoints">Rate Limiting your endpoints</h2>
<p>Let's face it. Not everybody in the world has best intentions for your architecture. Sure, attacks like DDoS are simply very complicated to mitigate, and even giants like GitHub go down when something like that happens. </p>
<p>But the least you can do is prevent a script-kiddie from taking down your server just because you have an expensive API endpoint exposed from your server without any rate-limiting in place. </p>
<p>If you use Express with Node, there are 2 beautiful packages which work seamlessly together to rate limit traffic on Layer 7:</p>
<ol>
<li>Express Rate Limit - <a target="_blank" href="https://www.npmjs.com/package/express-rate-limit">https://www.npmjs.com/package/express-rate-limit</a></li>
<li>Express Slow Down - <a target="_blank" href="https://www.npmjs.com/package/express-slow-down">https://www.npmjs.com/package/express-slow-down</a></li>
</ol>
<p>Express Slow Down actually adds incremental delay to your requests instead of dropping them. This way legit users, if they DDoS by accident (super activity of clicking buttons here and there), are simply slowed down and are not rate limited.</p>
<p>On the other hand, if there's a script-kiddie running scripts to take down the server, Express rate limiter monitors and rate limits that particular user, depending on the user IP, user account, or anything else you want.</p>
<p>Rate limiting could (should!) be applied on Layer 4 as well (Layer 4 means blocking traffic before discovering the contents of it - HTTP) through IP address. If you want, you can setup an NGiNX rule which blocks traffic on layer 4 and rejects the flood of traffic coming from a single IP, thus saving your server processes from overwhelming.</p>
<h2 id="heading-use-a-frontend-server-for-ssl-termination">Use a frontend server for SSL termination</h2>
<p>Node provides out of the box support for SSL handshakes with the browser using the <code>https</code> server module combined with the required SSL certs. </p>
<p>But let's be honest here, your application should not be concerned with SSL in the first place anyway. This is not something the application logic should do. Your Node code should only be responsible for what happens with the request, not the pre-processing and post-processing of data coming in and out of your server.</p>
<p>SSL termination refers to converting traffic from HTTPS to HTTP. And there are much better tools available than Node for that. I recommend NGiNX or HAProxy for it. Both have free versions available which get the job done and offload SSL termination from Node.</p>
<h2 id="heading-use-a-frontend-server-for-static-file-serving">Use a frontend server for static file serving</h2>
<p>Again, instead of using built in methods like <code>express.static</code> to serve static files, use frontend reverse proxy servers like NGiNX to serve static files from disk. </p>
<p>First of all, NGiNX can do that faster than Node (because it is built from scratch down to do only that). But it also offloads file serving from a single-threaded Node process which could use its clock cycles on something better.</p>
<p>Not only this – frontend proxy servers like NGiNX can also help you deliver content faster using GZIP compression. You can also set expiry headers, cache data, and much more, which is not something we should expect Node to do (however, Node can still do it).</p>
<h2 id="heading-configure-error-handling">Configure error handling</h2>
<p>Proper error handling can save you from hours of debugging and trying to reproduce difficult bugs. On server, it is especially easy to setup architecture for error handling because you're the one running it. I recommend tools like <a target="_blank" href="https://sentry.io">Sentry</a> with Node which records, reports, and emails you whenever the server crashes due to an error in the source code.</p>
<p>Once that is in place, now it is time to restart the server when it crashes so the whole site doesn't just go down for hours until you manually take it up again. </p>
<p>For this, you can use a process manager like <a target="_blank" href="https://www.npmjs.com/package/pm2">PM2</a>. Or even better, use a dockerized container environment with policies like <code>restart: always</code> with proper memory and disk limits setup. </p>
<p>Docker setup ensures that even if your container runs in OME, the process spins up again (which might not happen on a PM2 environment, as the OS might kill PM2 if there's a memory leak somewhere in a running process).</p>
<h2 id="heading-configure-logs-properly">Configure logs properly</h2>
<p>All the answers lie in logs. Server hacks, server crashes, suspicious user behavior, etc. For that, you have to make sure that:</p>
<ol>
<li>Each and every request attempt is logged with the IP address/method of request/path accessed, basically as much information as you can log (except for private information like passwords and credit card information, of course)</li>
<li>This can be achieved through the <a target="_blank" href="https://www.npmjs.com/package/morgan">morgan</a> package</li>
<li>Setup <strong>file stream logs</strong> on production instead of console output. This is faster, easier to see and allows you to export logs to online log viewing services.</li>
<li>Not all log messages have equal weight. Some logs are just there for debugging, while if some are present, it might indicate a pants-on-fire situation (like a server hack or unauthorized access). Use winston-logger for logging different levels of logs.</li>
<li>Setup <strong>log rotation</strong> so that you don't get a log size in GBs after a month or so, when you see the server.</li>
<li><strong>GZIP</strong> your log files after rotation. Text is cheap, and is highly compressible and easy to store. You should never face problem with text logs as long as they are compressed and you're running a server with a decent disk space (25GB+).</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>It is easy to take note of a few practices in production which could save you tears and hours of debugging later on. Make sure you follow these best practices and let me know what you think by saying Hi on my <a target="_blank" href="https://twitter.com/mehulmpt">twitter handle</a>.</p>
<p>If you liked this article, let's meet on social media. Here's my <a target="_blank" href="https://instagram.com/mehulmpt">Instagram</a> and <a target="_blank" href="https://twitter.com/mehulmpt">Twitter</a>. I'm super active, and would love to have a chat! Let's connect.</p>
<p>Peace!<br>Mehul</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Point your Domain to an S3 Website Bucket ]]>
                </title>
                <description>
                    <![CDATA[ By Clark Jason Ngo If you're hosting a static website in an S3 bucket and it's your first time buying a domain name, this simple guide is for you. Summary - What You Need Amazon S3 Have an S3 bucket with the same name as your domain name Upload your... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/cjn-how-to-point-your-domain-to-s3-website-bucket/</link>
                <guid isPermaLink="false">66d45e103a8352b6c5a2aa1b</guid>
                
                    <category>
                        <![CDATA[ dns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ S3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Hosting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 21 Mar 2020 00:08:34 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/domain_name_point_to_s3_bucket.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Clark Jason Ngo</p>
<p>If you're hosting a static website in an S3 bucket and it's your first time buying a domain name, this simple guide is for you.</p>
<h2 id="heading-summary-what-you-need">Summary - What You Need</h2>
<h3 id="heading-amazon-s3">Amazon S3</h3>
<ul>
<li>Have an S3 bucket with the same name as your domain name</li>
<li>Upload your website's code</li>
<li>Allow public access</li>
<li>Add a policy to enable S3 GetObject</li>
<li>Enable static website hosting</li>
</ul>
<h3 id="heading-domain-name-provider">Domain Name provider</h3>
<ul>
<li>In your domain name's DNS Zone settings, delete all <strong>A</strong> records</li>
<li>In DNS Zone settings, add <em>www</em> to <strong>subdomain</strong> and the S3 endpoint in hostname for <strong>CNAME</strong> records</li>
</ul>
<p>Let's go through these steps one by one.</p>
<h2 id="heading-step-1-create-an-s3-bucket">Step 1: Create an S3 bucket</h2>
<p>Create an S3 bucket to host your files for your website</p>
<p>First you need to create a bucket for your website. The name for your bucket must be the same as your domain name. Let's say we bought the domain name <strong>www.clarkngo.net</strong>. Then my S3 bucket's name should be <strong>www.clarkngo.net</strong> as well. </p>
<p>After configuration, my endpoint should look similar to this:</p>
<p>http://www.clarkngo.net.s3-website-us-west-2.amazonaws.com</p>
<p>Go to your AWS console and login. Choose S3.</p>
<ol>
<li>Click <strong>Buckets</strong></li>
<li>Click <strong>Create bucket</strong></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-119.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="3">
<li><p>Add your domain name in the <strong>bucket name</strong></p>
</li>
<li><p>You may choose any <strong>Region</strong></p>
</li>
</ol>
<h3 id="heading-creating-the-s3-bucket-and-general-configuration">Creating the S3 bucket and general configuration</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-118.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Follow the checkboxes below and click <strong>Create Bucket</strong>.</p>
<p>Only tick the following:</p>
<ul>
<li><strong>Block public access to bucket and objects granted through <em>new</em> access control lists (ACLs)</strong></li>
<li><strong>Block public access to bucket and objects granted through <em>any</em> access control lists (ACLs)</strong></li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-120.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-uploading-files-to-the-s3-bucket">Uploading files to the S3 Bucket</h3>
<ol>
<li>Click <strong>Overview</strong> and <strong>Upload</strong>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-121.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="2">
<li>Upload your website files in <strong>Select Files</strong></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-122.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="3">
<li><p>For <strong>Set permissions</strong>, hit <strong>Next</strong>.</p>
</li>
<li><p>For <strong>Set properties</strong>, hit <strong>Next</strong>. (The default is Standard S3.)</p>
</li>
<li><p>For <strong>Review</strong>, hit <strong>Upload</strong>.</p>
</li>
</ol>
<h3 id="heading-editing-the-bucket-policy">Editing the Bucket Policy</h3>
<ol>
<li>Click <strong>Permissions</strong>, then <strong>Bucket Policy</strong>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-123.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="2">
<li>Add the policy. (Note: For your website you'll change <strong>arn:aws::s3:::www.clarkngo.net/*</strong>)</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-124.png" alt="Image" width="600" height="400" loading="lazy"></p>
<pre><code>{
    <span class="hljs-string">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
    <span class="hljs-string">"Id"</span>: <span class="hljs-string">"Policy1548223592786"</span>,
    <span class="hljs-string">"Statement"</span>: [
        {
            <span class="hljs-string">"Sid"</span>: <span class="hljs-string">"Stmt1548223591553"</span>,
            <span class="hljs-string">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
            <span class="hljs-string">"Principal"</span>: <span class="hljs-string">"*"</span>,
            <span class="hljs-string">"Action"</span>: <span class="hljs-string">"s3:GetObject"</span>,
            <span class="hljs-string">"Resource"</span>: <span class="hljs-string">"arn:aws:s3:::www.clarkngo.net/*"</span>
        }
    ]
}
</code></pre><ol start="3">
<li>Hit <strong>Save</strong>.</li>
</ol>
<h3 id="heading-static-website-hosting">Static website hosting</h3>
<ol>
<li>Click <strong>Properties</strong>, then <strong>Static website hosting</strong>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-125.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="2">
<li><p>Choose <strong>Use this bucket to host a website</strong>.</p>
</li>
<li><p>For Index document, type <em>index.html</em>.</p>
</li>
<li><p>For Error document, type <em>index.html</em>.</p>
</li>
<li><p>Hit <strong>Save</strong>.</p>
</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-126.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-step-2-add-the-s3-endpoint-to-your-domain">Step 2: Add the S3 Endpoint to your Domain</h2>
<h3 id="heading-editing-your-dns-zone">Editing your DNS Zone</h3>
<ol>
<li>Login to your domain provider.</li>
<li>In this example, choose <strong>Name Servers/DNS</strong>, then <strong>Modify DNS Zone</strong> (or the equivalent).</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-127.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="3">
<li>Remove all <strong>A</strong> records in your domain. Usually it will have a default IP address for a 404 Not Found page.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-128.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="4">
<li><p>Add a <strong>CNAME</strong> to point to the S3 Bucket:</p>
</li>
<li><p>add <strong>www</strong> for the Subdomain.</p>
</li>
<li>add <strong>www.clarkngo.net.s3-website-us-west-2.amazonaws.com</strong> (the S3 Endpoint) to the Hostname.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-129.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And you're done! Note that it might take a while for your new settings take effect.</p>
<p>Connect with me in LinkedIn <a target="_blank" href="https://www.linkedin.com/in/clarkngo/">here</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-133.png" alt="Image" width="600" height="400" loading="lazy"></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Adobe XD vs Sketch vs Figma vs InVision - How to Pick the Best Design Software ]]>
                </title>
                <description>
                    <![CDATA[ Comparing Adobe XD vs Sketch vs Figma vs InVision studio is a very common topic among designers who are looking for the best design software. Sketch has long been the application of choice for UX and UI designers. But in the last four years, we have ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/adobe-xd-vs-sketch-vs-figma-vs-invision/</link>
                <guid isPermaLink="false">66c375a2e912451bdfbe18cf</guid>
                
                    <category>
                        <![CDATA[ Design Process ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ designer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ graphic design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Product Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Applications ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alexandru Paduraru ]]>
                </dc:creator>
                <pubDate>Wed, 05 Feb 2020 08:21:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/02/Adobe-xd-vs-Sketch-1024x576.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Comparing <strong>Adobe XD vs Sketch vs Figma vs InVision studio</strong> is a very common topic among designers who are looking for the best design software.</p>
<p>Sketch has long been the application of choice for UX and UI designers. But in the last four years, we have seen many new contenders for Sketch’s crown. Three of them that have made the biggest strides are Figma, Adobe XD, and InVision Studio.</p>
<p>These four tools have many pros in common but there are some differences too. For example, the first comparison, Adobe XD vs Sketch, makes sense especially since both have a similar interface which is user-friendly and has a minimalistic style.</p>
<p>In this article, I analyze how the most used design apps compete and what their unique features are using my experience acquired while working at <a target="_blank" href="https://www.creative-tim.com/?ref=freecodecamp">Creative Tim</a>.</p>
<p><img src="https://creativetimblog.com/blog/wp-content/uploads/2020/01/adobe-xd.png" alt="adobe xd" width="600" height="400" loading="lazy"></p>
<h3 id="heading-adobe-xdhttpswwwadobecomproductsxddetailshtml"><a target="_blank" href="https://www.adobe.com/products/xd/details.html"><strong>Adobe XD</strong></a></h3>
<p>Adobe XD was developed and published by Adobe Inc. XD, released on 18 October 2017. It is a vector-based user experience design tool for web apps, mobile apps, and voice apps available for macOS and Windows. There are versions for iOS and Android as well that help you preview the result of your work directly on mobile devices.</p>
<p>XD also support website wireframing and creating simple interactive click-through prototypes. With the character and layout tools of Adobe XD, Elements can be easily created and individual objects can be exported.</p>
<p>The interface is kept relatively simple, with a toolbar that is aligned at the side, as well as the large artboard area.</p>
<p>Comparing Adobe XD vs Sketch makes sense especially because of this similar interface which is user-friendly and has a minimalistic style.</p>
<p><img src="https://creativetimblog.com/blog/wp-content/uploads/2020/01/sketch.png" alt="sketch" width="600" height="400" loading="lazy"></p>
<h3 id="heading-sketchhttpswwwsketchcom"><a target="_blank" href="https://www.sketch.com/"><strong>Sketch</strong></a></h3>
<p>Sketch is a <a target="_blank" href="https://en.wikipedia.org/wiki/Vector_graphics_editor">vector graphics editor</a>, developed by the <a target="_blank" href="https://en.wikipedia.org/wiki/Netherlands">Dutch</a> company Bohemian Coding. Sketch was first released on 7 September 2010 for <a target="_blank" href="https://en.wikipedia.org/wiki/MacOS">macOS</a>. It won an <a target="_blank" href="https://en.wikipedia.org/wiki/Apple_Design_Awards">Apple Design Award</a> in 2012.</p>
<p>A key difference between Sketch and other vector graphics editors is that Sketch does not include print design features. Sketch is only available on macOS. This problem is partially solved by third party and handoff tools.</p>
<p>When Sketch first came out it completely disrupted the interface design space, but Adobe XD and Figma have recently come forward as new challengers. They offer unique functionality like prototyping and live collaboration.</p>
<p>I’ve recently been researching these tools for my side project, <a target="_blank" href="http://uxtools.co/">uxtools.co</a>, and wanted to share what I believe the be the most noteworthy decision points. Also, from my point of view, <a target="_blank" href="https://ahrefs.com/keywords-explorer/google/us/overview?keyword=learning%20to%20sketch">learning to sketch</a> is very useful and it does not take to much to become a Pro.</p>
<p><img src="https://creativetimblog.com/blog/wp-content/uploads/2020/01/figma.png" alt="figma" width="600" height="400" loading="lazy"></p>
<h3 id="heading-figmahttpswwwfigmacom"><a target="_blank" href="https://www.figma.com/"><strong>Figma</strong></a></h3>
<p>Figma came to the stage in 2016 <a target="_blank" href="https://techcrunch.com/2015/12/03/figma-vs-goliath/">with initial funding of $14M</a>.</p>
<p>With its seamless user interface and sleek feature palette, the tool quickly became a notorious competitor to similar solutions in the field.</p>
<p>Designers from brands like Twitter, Microsoft, GitHub, and Dropbox swear by Figma as the ultimate UI design tool.</p>
<p><img src="https://creativetimblog.com/blog/wp-content/uploads/2020/01/invision.png" alt="InVision Studio" width="600" height="400" loading="lazy"></p>
<h3 id="heading-invision-studiohttpswwwinvisionappcomstudio"><a target="_blank" href="https://www.invisionapp.com/studio"><strong>InVision Studio</strong></a></h3>
<p>InVision Studio is a new piece of software, released in 2019, that allows designers to build more advanced animation and micro-interactions. Studio also integrated with InVision’s link to Sketch via its Craft plugin.</p>
<p><strong>InVision Studio has got a nice dark UI by default</strong>, that helps developers focus on the work to be done in the evening. However, with macOS Mojave, every app can look like this quite easily. When they created it, they were inspired by another design tool - I am thinking about the Sketch app.</p>
<h2 id="heading-apps-comparison"><strong>Apps Comparison</strong></h2>
<h3 id="heading-1-pricing"><strong>1. Pricing</strong></h3>
<p>Budget can be a big deal when you’re working with your own resources. Some of these licenses have educational and promotional pricing (often 50% off), so don’t miss that part. For example, Figma will get you there for free as long as you're not working on a team.</p>
<ul>
<li><p><strong>Figma</strong>: Free for individuals! You can have 3 projects for free, or you can upgrade to unlimited projects and team functionality for $12/month (billed annually).</p>
</li>
<li><p><strong>Sketch</strong>: $99 per license that gets you the Mac App for life and access to the next production versions of the app.</p>
</li>
<li><p><strong>Adobe XD</strong>: It offers free and paid plans, depending on an individual's or team's needs. Paid plans start at $9.99/month.</p>
</li>
<li><p><strong>InVision Studio:</strong> Free right now.</p>
</li>
</ul>
<h3 id="heading-2-platform"><strong>2. Platform</strong></h3>
<p>Though Sketch has been immensely popular, it forces designers to only use Mac, which alienates developers from accessing design files.</p>
<ul>
<li><p><strong>Figma</strong>: Browser! Figma recently released a <a target="_blank" href="http://figma.com/downloads">Mac app</a> and <a target="_blank" href="https://www.figma.com/downloads">Windows app</a> (not offline-capable, though).</p>
</li>
<li><p><strong>Sketch</strong>: Mac only.</p>
</li>
<li><p><strong>Adobe XD</strong>: Mac and Windows. Subject to the same limitations as the CC suite.</p>
</li>
<li><p><strong>InVision Studio:</strong> Mac and Windows.</p>
</li>
</ul>
<h3 id="heading-3-live-collaboration"><strong>3. Live Collaboration</strong></h3>
<p>Nobody likes to send at the end of the day “version 3.0”, “version3.0.final”, “version3.0.final.final”. Live Collaboration can help us, especially live comments.</p>
<p>I imagine these were the same concerns that surrounded the release of the highly innovative Google Docs suite. Google Docs, however, turned the Microsoft Suite on its head with live collaboration, and now Figma is seeking to do the same thing with UI design.</p>
<ul>
<li><p><strong>Figma</strong>: Yes! Not to mention being browser-based, it allows Windows and even Linux users to have a very polished design tool.</p>
</li>
<li><p><strong>Sketch</strong>: Not natively, but a plugin, <a target="_blank" href="http://picnic.design/">Picnic</a>, is looking to change that. Also, they have <a target="_blank" href="https://www.sketch.com/teams/">Sketch for Teams</a>.</p>
</li>
<li><p><strong>Adobe XD</strong>: It offers real-time Coediting, launched at Adobe MAX 2019.</p>
</li>
<li><p><strong>InVision Studio:</strong> Not currently possible, but can generate share links.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/Sy3UzVS.png" alt="Live Collaboration" width="2864" height="1594" loading="lazy"></p>
<p><em>Image: Figma -</em> <a target="_blank" href="https://www.creative-tim.com/product/argon-design-system-pro?ref=freecodecamp"><em>Argon Design System Pro</em></a></p>
<h3 id="heading-4-handoff"><strong>4. Handoff</strong></h3>
<p>Recently a few apps have been developed specifically to deliver specs (sizing, spacing, color) to developers, but design tools are starting to integrate this functionality natively.</p>
<ul>
<li><p><strong>Figma</strong>: Because of live collaboration, developers can easily jump in (regardless of OS) and access the designs. Figma now neatly prints the handoff code for CSS, iOS, or Android in the right panel.</p>
</li>
<li><p><strong>Sketch</strong>: They've recently launched their own native developer handoff feature — Cloud Inspector. There’s even an entirely free alternative called Sketch measure that works just as well.</p>
</li>
<li><p><strong>Adobe XD</strong>: It offers design specs that allow a designer to create a shared link that contains measurements, assets, and automatically-generated CSS code snippets.</p>
</li>
<li><p><strong>InVision Studio:</strong> They have “Inspect Now”.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/5zY7ixi.png" alt="Handoff" width="2870" height="1494" loading="lazy"></p>
<p><em>Image: Figma -</em> <a target="_blank" href="https://www.creative-tim.com/product/argon-design-system-pro?ref=freecodecamp"><em>Argon Design System Pro</em></a></p>
<h3 id="heading-5-offline"><strong>5. Offline</strong></h3>
<p>This is so important. Some online apps can protect your information when Wifi goes down, but you need full access to open, use, and save from the app offline.</p>
<ul>
<li><p><strong>Figma</strong>: No, in an AMA they stated they don't have any current plans to add it.</p>
</li>
<li><p><strong>Sketch</strong>: Sure.</p>
</li>
<li><p><strong>Adobe XD</strong>: Yep.</p>
</li>
<li><p><strong>InVision Studio:</strong> Yes.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/PY9NsKh.png" alt="Offline" width="2866" height="1596" loading="lazy"></p>
<p><em>Image: AdobeXD -</em> <a target="_blank" href="https://www.creative-tim.com/product/argon-dashboard?ref=freecodecamp"><em>Argon Dashboard Free</em></a></p>
<h3 id="heading-6-prototyping"><strong>6. Prototyping</strong></h3>
<p>There are literally dozens of these apps nowadays, but they might become extinct as Adobe XD brings prototyping directly to the design tool. Keep your eye on these.</p>
<ul>
<li><p><strong>Figma</strong>: Yes! It's very basic but feels like Adobe XD without the transitions. Also, there's a nice <a target="_blank" href="https://medium.com/figma-design/introducing-figmas-integration-with-framer-c69a747aeee2">Framer</a> integration.</p>
</li>
<li><p><strong>Sketch</strong>: Yes!</p>
</li>
<li><p><strong>Adobe XD</strong>: Yes, native prototyping within the app. Adobe XD also supports voice prototyping and keyboard/gamepad support.</p>
</li>
<li><p><strong>InVision Studio:</strong> Yes, you can create prototypes and animations.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/5QZ8Rt1.png" alt="Prototyping" width="2812" height="1522" loading="lazy"></p>
<p><em>Image: InVision Studio -</em> <a target="_blank" href="https://www.creative-tim.com/product/argon-react-native?ref=freecodecamp"><em>Argon React Native</em></a></p>
<h3 id="heading-7-symbols"><strong>7. Symbols</strong></h3>
<p>Symbols can make your work easier. These have completely changed the design process. Forget building and duplicating list items over and over, let symbols do the work for you.</p>
<ul>
<li><p><strong>Figma</strong>: Good to go. Symbols now have states, constraints, and overrides.</p>
</li>
<li><p><strong>Sketch</strong>: The symbol functionality in Sketch is very impressive, and continues to improve. Symbols can be updated across entire documents and can resize responsively (that means less work for you when changing screen sizes).</p>
</li>
<li><p><strong>Adobe XD</strong>: It offers components that can be used throughout a document as well as linked across documents. It also allows designers to create variations of a component for different interactions, known as component states.</p>
</li>
<li><p><strong>InVision Studio:</strong> they have components that are a close approximation to the symbol conventions found in other applications. Components in their final form will honor a broad, scalable hierarchy that allows designers to quickly build-up, mix, and match components intelligently across their designs.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/9lfwDD5.png" alt="Symbols" width="2874" height="1600" loading="lazy"></p>
<p><em>Image: Sketch -</em> <a target="_blank" href="https://www.creative-tim.com/product/material-kit-pro?ref=freecodecamp"><em>Material Kit Pro</em></a></p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Sketch has a big disadvantage here because it is only available for Mac users. And as such, it lets tools like Figma and Adobe XD innovate beyond the basic necessities.</p>
<p>Also, in terms of design tools, Adobe XD provides a robust set of responsive while the Sketch doesn’t have this feature built-in (but it has many plugins). If your tool does something better than the other, it is often enough of a reason to switch over. The browser-based approach that Figma has taken is also something to behold.</p>
<p>When talking about Adobe XD vs Sketch, the first one’s future is looking very bright and will win over many Sketch users. InVision’s change of focus may ensure its survival but one thing is for certain - Adobe XD is here to stay. The Adobe powerhouse is strong, and smaller companies like InVision and Sketch will have to work hard to stay relevant in the future.</p>
<p>People usually prefer to design and work in just one place. If you’re a part of a team, then Figma is undoubtedly for you.</p>
<p><img src="https://i.imgur.com/YaMctAr.png" alt="conclusions" width="2522" height="1932" loading="lazy"></p>
<p><strong>After all of that: first is Figma, second is Sketch, third is Adobe XD and fourth is InVision Studio.</strong></p>
<p>Overall, when talking about the best design software, these four tools are extremely well-suited for modern designer needs.</p>
<p>Try all four out to see which one is better for your use cases. I hope this comparison - Adobe XD vs Sketch vs Figma vs InVision - helped you decide which design tool is better for you.</p>
<p>Resources:</p>
<p><a target="_blank" href="https://www.figma.com/figma-vs-sketch/">https://www.figma.com/figma-vs-sketch/</a></p>
<p><a target="_blank" href="https://uxtools.co/blog/sketch-vs-adobe-xd-vs-figma/">https://uxtools.co/blog/sketch-vs-adobe-xd-vs-figma/</a></p>
<p><a target="_blank" href="https://www.codeinwp.com/blog/figma-vs-sketch-vs-adobe-xd/">https://www.codeinwp.com/blog/figma-vs-sketch-vs-adobe-xd/</a></p>
<p><a target="_blank" href="https://support.invisionapp.com/hc/en-us/sections/360004450191-Studio">https://support.invisionapp.com/hc/en-us/sections/360004450191-Studio</a></p>
<p><a target="_blank" href="https://helpx.adobe.com/ro/xd/help/components.html">https://helpx.adobe.com/ro/xd/help/components.html</a></p>
<p><a target="_blank" href="https://www.sketch.com/docs/">https://www.sketch.com/docs/</a></p>
 ]]>
                </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>
        
            <item>
                <title>
                    <![CDATA[ How to Learn to Code and Get Your First Job ]]>
                </title>
                <description>
                    <![CDATA[ By Glyn Lewington How I Learned to Code and Got My First Job My coding journey began about two and a half years ago, and I started working my first full-time developer job recently (wooo!). This might seem like a long time for some of you, but I didn... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learning-to-code-your-first-job/</link>
                <guid isPermaLink="false">66d45ede182810487e0ce18a</guid>
                
                    <category>
                        <![CDATA[ internships ]]>
                    </category>
                
                    <category>
                        <![CDATA[ job ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Job Change ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Job Hunting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Job Interview ]]>
                    </category>
                
                    <category>
                        <![CDATA[ jobs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 30 Oct 2019 10:02:15 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9fc0740569d1a4ca445a.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Glyn Lewington</p>
<h2 id="heading-how-i-learned-to-code-and-got-my-first-job">How I Learned to Code and Got My First Job</h2>
<p>My coding journey began about two and a half years ago, and I started working my first full-time developer job recently (wooo!). This might seem like a long time for some of you, but I didn't rush it and wasn't trying to find work until two months ago. Many people have done it more quickly and I was probably ready for a while. So I've decided to share my story, my resources, and what worked for me when learning web development.</p>
<h2 id="heading-how-i-got-interested-in-coding">How I got interested in coding</h2>
<p>I was living in Thailand, training and fighting Muay Thai while working about 10 hours a week as a social media manager. I wasn't really enjoying marketing as a career and it wasn't as flexible as I wished, since I needed to be active at certain hours of the day. </p>
<p>Luckily I had the time to learn something new. I'd looked at a few things online which sounded like good skills to have that were flexible and that could be done remotely. But it wasn't until I met a guy traveling through Vietnam, who was working as a web developer, that I was intrigued and started to play around a little bit with coding.</p>
<h2 id="heading-where-to-learn">Where To Learn?</h2>
<p>At first, I was jumping around trying out different sites such as Codecademy, freeCodeCamp, and others I can't recall. I never really got anywhere with these to start with but they got me interested. </p>
<p>After researching, I decided to take CS50 - Introduction To Computer Science, a famous Harvard course run by David Malan. It teaches the real basics of computer science such as data structures, algorithms, and the relevant workings of a computer. This is all done in C but the basics you learn and the confidence you build apply to every language.</p>
<p>Once I completed CS50 I started on freeCodeCamp. What I loved about freeCodeCamp most was the projects. They give you great ideas to practice and test your skills as you are learning. Once I got through the first couple of sections on HTML/CSS/JavaScript and onto more advanced topics, I didn't find the lessons thorough enough. So I ditched them for Udemy courses which went more in depth on a topic. Then I could go back and build the freeCodeCamp projects for practice.</p>
<p>I used this combination of Udemy and freeCodeCamp until I had a solid grasp of HTML, CSS, JavaScript, Node, React, and Redux. I also completed all of the projects on freeCodeCamp except for the data visualisation section using D3.js, as I didn't find this skill in demand when looking at jobs.</p>
<h2 id="heading-what-next">What Next?</h2>
<p>Although I was confident in these skills, I still hadn't gotten involved in open source except for a couple of tiny pull requests. I simply didn't know where to get started. Every time I looked at issues I couldn't see anything interesting. Or those that were interesting had already been claimed by someone else. </p>
<p>Eventually, I got involved with freeCodeCamp as a contributor. I would recommend just making a habit of checking the issues once a week or so to see if there's something that you want to help with. </p>
<p>Along with my work with open source, I also got an internship as a front-end developer focused on React. It wasn't the ideal internship but it was remote and I learned a lot by working on a codebase someone else had built. I was the only dev on the front-end. This presented it's own challenges, like being given a problem and being responsible for researching and solving it. In this time, I learned about and implemented internationalisation as well as React Native.</p>
<h2 id="heading-getting-the-job">Getting the Job</h2>
<p>I had a strong mix of skills, projects and experience to show off, my résumé in hand, and a <a target="_blank" href="https://glynlewington.com">portfolio site</a> promoting my work. I was ready!</p>
<p>Getting the job was mostly a game of patience. All together it took me 2 months of searching and applying every day to jobs. Most of the time I didn't hear back. I applied for a lot of jobs which were looking for mid level developers or more experience than I had, which didn't work out. Most of the jobs I found on job boards were advertised by recruiters and I found these the most fruitful. I often received a call and meeting with recruiters who were impressed by my résumé and skills and were looking for junior roles for me.</p>
<p>I was also attending meetups to network and look for jobs. I didn't find any roles directly, as the companies weren't looking for juniors. However, I did meet a recruiter at a React meetup whom I grabbed coffee with the next week. He had a role from a company that was open to juniors and this is where I ended up accepting a position.</p>
<p>The hiring process for this position consisted of a tech test (https://github.com/GlynL/tech-test-prendi), and then an interview where I was actually offered the job at the end. It's a great small company where I'm working with the senior developer and can bounce ideas and get help when I need it. It's a full-stack job, I get to use React daily, and I will get the chance to work with a lot of technologies as projects require them.</p>
<p>When I was interviewing, the thing that people appreciated most was that I had worked on a real application in an internship. Even if I could have done everything in a personal project it proved that I could work on a real world application with other people. I would certainly recommend seeking out internships as this will look great on your résumé and will be a talking point during interviews.</p>
<h2 id="heading-what-would-i-do-differently">What would I do differently?</h2>
<p>If I were to do it all over again, there's a couple of things I would do differently. </p>
<p>For starters, I would get more involved with open source projects much earlier on. There's always something you can contribute to a project even if you are still learning HTML and CSS. You may have to be more particular about the issues you pick up but you can definitely help! The skills you gain in navigating a large codebase and working with others are invaluable. And as you learn more you can pick more complex issues to match your skills.</p>
<p>Secondly, I would also start networking earlier as this might've led to securing internships and/or junior positions. If people know you are searching for an opportunity then they will think of you when they have something. Or it'll at least give you an advantage in the application process as they will know who you are and that you have a genuine interest in the field.</p>
<p>Please feel free to let me know if you have any questions or would like me to elaborate on any of the points. I'd be happy to help!</p>
<p>You can contact and connect with me on Twitter <a target="_blank" href="https://twitter.com/GlynWebDev">@glynwebdev</a>.  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A portable Makefile for continuous delivery with Hugo and GitHub Pages ]]>
                </title>
                <description>
                    <![CDATA[ Fun fact: I first launched my GitHub Pages site 1,018 days ago. Since then, we’ve grown together. From early cringe-worthy commit messages, through eighty-six versions of Hugo, and up until last week, a less-than-streamlined multi-app continuous inte... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-portable-makefile-for-continuous-delivery-with-hugo-and-github-pages/</link>
                <guid isPermaLink="false">66bd8f07de1f3ee5a6a8f4c7</guid>
                
                    <category>
                        <![CDATA[ continuous delivery ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Continuous Integration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Mon, 21 Oct 2019 17:09:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/10/cover-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><img src="https://www.freecodecamp.org/news/content/images/2019/10/cover.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Fun fact: I first launched <a target="_blank" href="https://victoria.dev">my GitHub Pages site</a> 1,018 days ago.</p>
<p>Since then, we’ve grown together. From early cringe-worthy commit messages, through eighty-six versions of <a target="_blank" href="https://gohugo.io/">Hugo</a>, and up until last week, a less-than-streamlined multi-app continuous integration and deployment (CI/CD) workflow.</p>
<p>If you know me at all, you know I love to automate things. I’ve been  using a combination of AWS Lambda, Netlify, and Travis CI to  automatically build and publish this site. My workflow for the task  includes:</p>
<ul>
<li>Build with <a target="_blank" href="https://gohugo.io/">Hugo</a> on push to master, and on a schedule (Netlify and Lambda);</li>
<li>Optimize and resize images (Netlify);</li>
<li>Test with <a target="_blank" href="https://github.com/gjtorikian/html-proofer">HTMLProofer</a> (Travis CI); and</li>
<li>Deploy to my <a target="_blank" href="https://victoria.dev/blog/two-ways-to-deploy-a-public-github-pages-site-from-a-private-hugo-repository/">separate, public, GitHub Pages repository</a> (Netlify).</li>
</ul>
<p>Thanks to the introduction of GitHub Actions, I’m able to do all the above with just one portable <a target="_blank" href="https://en.wikipedia.org/wiki/Makefile">Makefile</a>.</p>
<p>Next week I’ll cover my Actions set up; today, I’ll take you through the nitty-gritty of my Makefile so you can write your own.</p>
<h2 id="heading-makefile-portability">Makefile portability</h2>
<p><a target="_blank" href="https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html">POSIX-standard-flavour Make</a> runs on every Unix-like system out there. <a target="_blank" href="https://en.wikipedia.org/wiki/Make_(software)#Derivatives">Make derivatives</a>, such as <a target="_blank" href="https://www.gnu.org/software/make/">GNU Make</a> and several flavours of BSD Make also run on Unix-like systems, though  their particular use requires installing the respective program. To  write a truly portable Makefile, mine follows the POSIX standard. (For a  more thorough summation of POSIX-compatible Makefiles, I found this  article helpful: <a target="_blank" href="https://nullprogram.com/blog/2017/08/20/">A Tutorial on Portable Makefiles</a>.) I run Ubuntu, so I’ve tested the portability aspect using the BSD Make programs <code>bmake</code>, <code>pmake</code>, and <code>fmake</code>.  Compatibility with non-Unix-like systems is a little more complicated,  since shell commands differ. With derivatives such as Nmake, it’s better  to write a separate Makefile with appropriate Windows commands.</p>
<p>While much of my particular use case could be achieved with shell  scripting, I find Make offers some worthwhile advantages. I enjoy the  ease of using variables and <a target="_blank" href="https://en.wikipedia.org/wiki/Make_(software)#Macros">macros</a>, and the modularity of <a target="_blank" href="https://en.wikipedia.org/wiki/Makefile#Rules">rules</a> when it comes to organizing my steps.</p>
<p>The writing of rules mostly comes down to shell commands, which is  the main reason Makefiles are as portable as they are. The best part is  that you can do pretty much <em>anything</em> in a terminal, and certainly handle all the workflow steps listed above.</p>
<h2 id="heading-my-continuous-deployment-makefile">My continuous deployment Makefile</h2>
<p>Here’s the portable Makefile that handles my workflow. Yes, I put emojis in there. I’m a monster.</p>
<pre><code class="lang-makefile"><span class="hljs-section">.POSIX:</span>
DESTDIR=public
HUGO_VERSION=0.58.3

OPTIMIZE = find <span class="hljs-variable">$(DESTDIR)</span> -not -path <span class="hljs-string">"*/static/*"</span> \( -name '*.png' -o -name '*.jpg' -o -name '*.jpeg' \) -print0 | \
xargs -0 -P8 -n2 mogrify -strip -thumbnail '1000&gt;'

<span class="hljs-meta"><span class="hljs-meta-keyword">.PHONY</span>: all</span>
<span class="hljs-section">all: get_repository clean get build test deploy</span>

<span class="hljs-meta"><span class="hljs-meta-keyword">.PHONY</span>: get_repository</span>
<span class="hljs-section">get_repository:</span>
    @echo <span class="hljs-string">"? Getting Pages repository"</span>
    git clone https://github.com/victoriadrake/victoriadrake.github.io.git <span class="hljs-variable">$(DESTDIR)</span>

<span class="hljs-meta"><span class="hljs-meta-keyword">.PHONY</span>: clean</span>
<span class="hljs-section">clean:</span>
    @echo <span class="hljs-string">"? Cleaning old build"</span>
    cd <span class="hljs-variable">$(DESTDIR)</span> &amp;&amp; rm -rf *

<span class="hljs-meta"><span class="hljs-meta-keyword">.PHONY</span>: get</span>
<span class="hljs-section">get:</span>
    @echo <span class="hljs-string">"❓ Checking for hugo"</span>
    @if ! [ -x <span class="hljs-string">"$$(command -v hugo)"</span> ]; then\
        echo <span class="hljs-string">"? Getting Hugo"</span>;\
        wget -q -P tmp/ https://github.com/gohugoio/hugo/releases/download/v<span class="hljs-variable">$(HUGO_VERSION)</span>/hugo_extended_<span class="hljs-variable">$(HUGO_VERSION)</span>_Linux-64bit.tar.gz;\
        tar xf tmp/hugo_extended_<span class="hljs-variable">$(HUGO_VERSION)</span>_Linux-64bit.tar.gz -C tmp/;\
        sudo mv -f tmp/hugo /usr/bin/;\
        rm -rf tmp/;\
        hugo version;\
    fi

<span class="hljs-meta"><span class="hljs-meta-keyword">.PHONY</span>: build</span>
<span class="hljs-section">build:</span>
    @echo <span class="hljs-string">"? Generating site"</span>
    hugo --gc --minify -d <span class="hljs-variable">$(DESTDIR)</span>

    @echo <span class="hljs-string">"? Optimizing images"</span>
    <span class="hljs-variable">$(OPTIMIZE)</span>

<span class="hljs-meta"><span class="hljs-meta-keyword">.PHONY</span>: test</span>
<span class="hljs-section">test:</span>
    @echo <span class="hljs-string">"? Testing HTML"</span>
    docker run -v <span class="hljs-variable">$(GITHUB_WORKSPACE)</span>/<span class="hljs-variable">$(DESTDIR)</span>/:/mnt 18fgsa/html-proofer mnt --disable-external

<span class="hljs-meta"><span class="hljs-meta-keyword">.PHONY</span>: deploy</span>
<span class="hljs-section">deploy:</span>
    @echo <span class="hljs-string">"? Preparing commit"</span>
    @cd <span class="hljs-variable">$(DESTDIR)</span> \
    &amp;&amp; git config user.email <span class="hljs-string">"hello@victoria.dev"</span> \
    &amp;&amp; git config user.name <span class="hljs-string">"Victoria via GitHub Actions"</span> \
    &amp;&amp; git add . \
    &amp;&amp; git status \
    &amp;&amp; git commit -m <span class="hljs-string">"? CD bot is helping"</span> \
    &amp;&amp; git push -f -q https://<span class="hljs-variable">$(TOKEN)</span>@github.com/victoriadrake/victoriadrake.github.io.git master
    @echo <span class="hljs-string">"? Site is deployed!"</span>
</code></pre>
<p>Sequentially, this workflow:</p>
<ol>
<li>Clones the public Pages repository;</li>
<li>Cleans (deletes) the previous build files;</li>
<li>Downloads and installs the specified version of Hugo, if Hugo is not already present;</li>
<li>Builds the site;</li>
<li>Optimizes images;</li>
<li>Tests the built site with HTMLProofer, and</li>
<li>Prepares a new commit and pushes to the public Pages repository.</li>
</ol>
<p>If you’re familiar with command line, most of this may look familiar.  Here are a couple bits that might warrant a little explanation.</p>
<h3 id="heading-checking-if-a-program-is-already-installed">Checking if a program is already installed</h3>
<p>I think this bit is pretty tidy:</p>
<pre><code class="lang-sh"><span class="hljs-keyword">if</span> ! [ -x <span class="hljs-string">"$<span class="hljs-subst">$(command -v hugo)</span>"</span> ]; <span class="hljs-keyword">then</span>\
...
<span class="hljs-keyword">fi</span>
</code></pre>
<p>I use a negated <code>if</code> conditional in conjunction with <code>command -v</code> to check if an executable (<code>-x</code>) called <code>hugo</code> exists. If one is not present, the script gets the specified version of Hugo and installs it. <a target="_blank" href="https://stackoverflow.com/a/677212">This Stack Overflow answer</a> has a nice summation of why <code>command -v</code> is a more portable choice than <code>which</code>.</p>
<h3 id="heading-image-optimization">Image optimization</h3>
<p>My Makefile uses <code>mogrify</code> to batch resize and compress  images in particular folders. It finds them automatically using the file  extension, and only modifies images that are larger than the target  size of 1000px in any dimension. I wrote more about the <a target="_blank" href="https://victoria.dev/blog/how-to-quickly-batch-resize-compress-and-convert-images-with-a-bash-one-liner/">batch-processing one-liner in this post</a>.</p>
<p>There are a few different ways to achieve this same task, one of which, theoretically, is to take advantage of Make’s <a target="_blank" href="https://en.wikipedia.org/wiki/Make_(software)#Suffix_rules">suffix rules</a> to run commands only on image files. I find the shell script to be more readable.</p>
<h3 id="heading-using-dockerized-htmlproofer">Using Dockerized HTMLProofer</h3>
<p>HTMLProofer is installed with <code>gem</code>, and uses Ruby and <a target="_blank" href="https://nokogiri.org/tutorials/ensuring_well_formed_markup.html">Nokogiri</a>, which adds up to a lot of installation time for a CI workflow. Thankfully, <a target="_blank" href="https://github.com/18F">18F</a> has a <a target="_blank" href="https://github.com/18F/html-proofer-docker">Dockerized version</a> that is much faster to implement. Its usage requires starting the container with the built site directory <a target="_blank" href="https://docs.docker.com/storage/volumes/#start-a-container-with-a-volume">mounted as a data volume</a>, which is easily achieved by appending to the <code>docker run</code> command.</p>
<pre><code class="lang-sh">docker run -v /absolute/path/to/site/:/mounted-site 18fgsa/html-proofer /mounted-site
</code></pre>
<p>In my Makefile, I specify the absolute site path using the <a target="_blank" href="https://help.github.com/en/articles/virtual-environments-for-github-actions#environment-variables">default environment variable</a> <code>GITHUB_WORKSPACE</code>. I’ll dive into this and other GitHub Actions features in the next post.</p>
<p>In the meantime, happy Making!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Make Sense of Google Analytics and the Traffic to Your Website ]]>
                </title>
                <description>
                    <![CDATA[ Google Analytics is a powerful web service that gives you insights into your website. But exactly can it help you? I’m going to cover a few things here. If you’re already familiar with the basics, feel free to skip around: What is Google Analytics? ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/making-sense-of-google-analytics-and-the-traffic-to-your-website/</link>
                <guid isPermaLink="false">66b8e38047c23b7ae1ad0bdd</guid>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #reporting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SEO ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Wed, 04 Sep 2019 14:32:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/09/making-sense-of-google-analytics.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><a target="_blank" href="https://marketingplatform.google.com/about/analytics/">Google Analytics</a> is a powerful web service that gives you insights into your website. But exactly can it help <em>you</em>?</p>
<p>I’m going to cover a few things here. If you’re already familiar with the basics, feel free to skip around:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/making-sense-of-google-analytics-and-the-traffic-to-your-website/#what-is-google-analytics">What is Google Analytics?</a> (A quick overview)</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/making-sense-of-google-analytics-and-the-traffic-to-your-website/#okay-so-where-do-i-start">Okay, so where do I start?</a> (Quick start install guide)</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/making-sense-of-google-analytics-and-the-traffic-to-your-website/#what-are-some-quick-insights">What are some quick insights?</a> (Basic out of the box reports)</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/making-sense-of-google-analytics-and-the-traffic-to-your-website/#bonus-advanced-insights">Bonus: Advanced Insights</a> (Custom Dimensions)</li>
</ul>
<p>So let’s start from the top.</p>
<h2 id="heading-what-is-google-analytics"><strong>What is Google Analytics?</strong></h2>
<blockquote>
<p>Google Analytics gives you the tools you need to better understand your customers. You can then use those business insights to take action, such as improving your website, creating tailored audience lists, and more. - <a target="_blank" href="https://marketingplatform.google.com/about/analytics/">Google's official documentation</a></p>
</blockquote>
<p>More simply put, Google Analytics (GA) is a web analytics service provided by Google on the <a target="_blank" href="https://marketingplatform.google.com/about/">Google Marketing Platform</a>. It allows you to track and measure your website’s traffic with powerful insights and reports.</p>
<p>GA can work a few different ways, but the most common is <a target="_blank" href="https://support.google.com/analytics/answer/1008080?hl=en">using a quick drop-in JavaScript snippet</a> that goes on every page of your website (typically the <code>&lt;head&gt;</code>).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-37.png" alt="Image" width="600" height="400" loading="lazy">
<em>Google Analytics lets you measure user interaction with websites.</em></p>
<p>The base version of Google Analytics is free. You have the option of upgrading to the 360 suite, which will open up some feature limits, but most of you probably don’t need this as it is more geared towards high traffic websites.</p>
<h3 id="heading-why-do-i-need-google-analytics"><strong>Why do I need Google Analytics?</strong></h3>
<p>You don’t <em>need</em> it. But you can get an incredible amount of insight from GA with even a basic out of the box setup. </p>
<p>GA is helpful if you're a developer trying to get more traffic out of your blog, or a business trying to optimize your sales funnel. </p>
<p>GA helps you answer simple questions like:</p>
<ul>
<li>Where is my traffic coming from?</li>
<li>What pages get the most traffic?</li>
<li>What are the most popular devices people visit on?</li>
</ul>
<p>Not only can this help you make better-educated decisions with your website. It can also help you unveil user experience concerns, or save money due to site issues by keeping an eye on traffic trends and user interactions.</p>
<h2 id="heading-okay-so-where-do-i-start"><strong>Okay, so where do I start?</strong></h2>
<p>Google makes it’s fairly easy for any developer to jump in and get started. The only real prerequisite is that you set up an account. Google themselves offers a great <a target="_blank" href="https://support.google.com/analytics/answer/1008015?hl=en">step-by-step and constantly updated guide</a>, so I’ll leave it to them.</p>
<h3 id="heading-getting-the-tag-on-your-page"><strong>Getting the tag on your page</strong></h3>
<p>Once you’re logged into the Google Analytics Dashboard, go to the Admin section, which you can find on the left hand side of the page:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-42.png" alt="Image" width="600" height="400" loading="lazy">
<em>Admin link in the Google Analytics Dashboard</em></p>
<p>Once in the admin section, you can navigate to Tracking Info then Tracking code under the property you want to track.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-43.png" alt="Image" width="600" height="400" loading="lazy">
<em>Tracking code link in the Google Analytics Admin</em></p>
<p>Finally, you can find the JavaScript snippet that you can throw in the head of your website. Remember, this should be on ALL pages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-44.png" alt="Image" width="600" height="400" loading="lazy">
<em>Google Analytic tracking code snippet</em></p>
<h3 id="heading-let-the-traffic-flow"><strong>Let the traffic flow</strong></h3>
<p>From here you just have to give it time. Google Analytics won’t have historical data, it will only have the the new traffic that hit your page once the snippet was installed. </p>
<p>You can check it’s working by visiting the Realtime Report and either hitting the page in another tab or seeing your visitors hit the page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-45.png" alt="Image" width="600" height="400" loading="lazy">
<em>Google Analytics Realtime Report</em></p>
<h3 id="heading-more-settings-more-configuration"><strong>More settings, more configuration</strong></h3>
<p>Google Analytics is a complex machine and can do a lot. Start slow and try to understand what’s happening before moving too fast turning every different switch. </p>
<p>Once you're comfortable, there are a lot of <a target="_blank" href="https://www.google.com/search?q=google+analytics+tips">great guides out there</a> for beginners and advanced users alike to unleash the full power of your reporting capabilities.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/super-saiyan.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Goku going Super Saiyan</em></p>
<h2 id="heading-what-are-some-quick-insights"><strong>What are some quick insights?</strong></h2>
<p>Cool, so you have GA installed, you see your traffic, and you’re ready to get started looking at your reports, but where to begin?</p>
<h3 id="heading-what-pages-get-the-most-traffic"><strong>What pages get the most traffic?</strong></h3>
<p>Let’s start with a simple one. Which pages of my website are getting the most traffic? To find this out we’ll want to view the Behavior Overview, which we can find by visiting Behavior then Overview.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-46.png" alt="Image" width="600" height="400" loading="lazy">
<em>Finding top page on Google Analytics Behavior Overview Report</em></p>
<p>Above we’re looking at the full month of August, which you can change with the date picker in the top right of the report. We can see overall, we had 3,853,265 total pageviews and 121,187 of them were to /news, the freeCodeCamp News homepage, which was our most popular page of the month.</p>
<h3 id="heading-where-is-my-traffic-coming-from"><strong>Where is my traffic coming from?</strong></h3>
<p>A common question is: “where are people coming from?” How are people actually finding my website? This is a 2 parter, let’s start with overall traffic.</p>
<p>A good way to start is by finding the Acquisition Overview page. You can navigate there by selecting Acquisition than Overview.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-47.png" alt="Image" width="600" height="400" loading="lazy">
<em>Finding top traffic source on Google Analytics Acquisition Overview Report</em></p>
<p>Shown above, the majority of traffic comes from organic searches on Google, a little over 75% in fact. That’s some good <a target="_blank" href="https://moz.com/beginners-guide-to-seo">SEO</a>!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-48.png" alt="Image" width="600" height="400" loading="lazy">
<em>Outstanding Move</em></p>
<p>But what if we wanted to see how people are getting to a particular post? This involves a little more work, but let’s dive in.</p>
<p>Let’s go back to Behavior in the sidebar, then Site Content, and finally Landing Pages. Once there, you can use the search to find your post as shown below and select it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-49.png" alt="Image" width="600" height="400" loading="lazy">
<em>Searching for a page on the Google Analytics Landing Page Report</em></p>
<p>After you found your post, we’re going to add a Secondary dimension. In particular, we’ll want to find and select “Source / Medium” in the Secondary dimension dropdown.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-50.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding a Secondary dimension on the Google Analytics Landing Page Report</em></p>
<p>Finally we’ll have an idea of where people are coming from to visit our post.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-51.png" alt="Image" width="600" height="400" loading="lazy">
<em>Finding the top Source / Medium on the Google Analytics Landing Page Report</em></p>
<p>It seems like this is following the trend of great Organic SEO. If you notice though, we have “(direct) / (none)” as the second highest source / medium. </p>
<p>Unfortunately, it’s not always that easy. And if Google Analytics can’t figure out where the user came from, it will mark it as “(direct) / (none)”. <a target="_blank" href="https://moz.com/blog/guide-to-direct-traffic-google-analytics">While that’s solvable</a>, and sometimes actually means something, we can see the majority comes from simple searches on Google itself.</p>
<h3 id="heading-what-are-the-most-popular-devices-people-visit-on"><strong>What are the most popular devices people visit on?</strong></h3>
<p>Understanding what devices your visitors are using is an incredibly helpful tool for optimizing User Experience, as well as maximizing potential revenue by making sure your site works. </p>
<p>In a perfect world, your website would work in all browsers. But we may be able to safely rule out certain older browsers.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-52.png" alt="Image" width="600" height="400" loading="lazy">
<em>Internet Explorer behind a tree</em></p>
<p>To get started, find your way to Audience then Overview. Once there, select Browsers in the list as shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-53.png" alt="Image" width="600" height="400" loading="lazy">
<em>Finding the top browser in the Google Analytics Acquisition Report</em></p>
<p>We can see that luckily, our top browsers are dominated by modern ones, with Chrome carrying a cool 76.42%. </p>
<p>But wait, Internet Explorer is pulling 1.06% or 22,499, which isn’t something to bat an eye at. So let’s dig in a little more by clicking on Internet Explorer.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-54.png" alt="Image" width="600" height="400" loading="lazy">
<em>Finding the traffic for Internet Explorer versions in the Google Analytics Acquisition Browser Report</em></p>
<p>Phew, I think we’re safe. Now we can see how many people visit each version of Internet Explorer and luckily almost 99% of THAT traffic is IE9 or above. While we should be as inclusive as we can, this can help us determine priority and make decisions on <a target="_blank" href="https://caniuse.com/">what browser versions to officially support</a>.</p>
<p>Real talk: 5 people on IE5? ?</p>
<h2 id="heading-bonus-advanced-insights"><strong>Bonus: Advanced Insights</strong></h2>
<p>Out of the box, Google Analytics is powerful, but with some customization and deeper integration with your web data, you can give your analytics dashboard extra superpowers.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/darkwing-duck-lets-get-dangerous.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Darkwing Duck Let's Get Dangerous</em></p>
<h2 id="heading-custom-dimensions"><strong>Custom Dimensions</strong></h2>
<p><a target="_blank" href="https://support.google.com/analytics/answer/2709829?hl=en">Custom Dimensions</a> are what Google specifies as “non-standard data.” Really, they’re just additional data points that we can configure to get a better understanding of what makes our website unique.</p>
<p>For the sake of this article (maybe a later one), I’m not going to go into how to add Custom Dimensions, but Google provides a <a target="_blank" href="https://support.google.com/analytics/answer/2709828?hl=en">great guide to get an in depth understanding</a> and a <a target="_blank" href="https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets">developer guide to go with it</a>. What I’ll go over here is how to explore our reports once some Custom Dimensions are already set up.</p>
<h3 id="heading-what-are-our-custom-dimensions"><strong>What are our Custom Dimensions?</strong></h3>
<p>To start, we’ll talk about 2 specific Custom Dimensions: Author and Page Category. </p>
<p>Author is what it sounds like, it’s the person who wrote the article. Page Category in our case is the primary, top-level category that represents the post. </p>
<p>On freeCodeCamp News, you can specify as many categories as you want (do so responsibly), but the first one in the list is consider your “primary” category and is used when you see your post in listing views such as the homepage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-55.png" alt="Image" width="600" height="400" loading="lazy">
<em>Post on freeCodeCamp News Homepage</em></p>
<h3 id="heading-what-can-we-do-with-these"><strong>What can we do with these?</strong></h3>
<p>The great thing is when we set these up, we attribute them to a page view. Once that page view is collected by Google Analytics, we can use it to search on, which is really what makes it powerful. Let’s start with Author.</p>
<h3 id="heading-finding-all-posts-from-a-specific-author"><strong>Finding all posts from a specific Author</strong></h3>
<p>If we wanted to search for any post written by Quincy Larson, we’ll want to navigate back to <strong>Behavior</strong>, then <strong>Site Content</strong>, and finally <strong>All Pages</strong>.</p>
<p>Once there, we’ll want to add a <strong>Secondary dimension</strong>, similar when we added Source / medium, but now we’ll want to search for and select <strong>Author</strong>, which you’ll also find nested under the Custom Dimensions heading of that dropdown.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-56.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting Author as a Secondary dimension on the Google Analytics Behavior Report</em></p>
<p>From there, we’ll want to select Advanced on the right (highlighted below), add our author’s name, and finally hit the Apply button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-57.png" alt="Image" width="600" height="400" loading="lazy">
<em>Searching for an Author in Advanced Search of Google Analytics Behavior Report</em></p>
<p>After hitting apply, we now have all the stats we could ever dream of for the articles written by our author, Quincy Larson.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-58.png" alt="Image" width="600" height="400" loading="lazy">
<em>All posts from an Author in Google Analytics Behavior Report</em></p>
<h3 id="heading-you-can-also-just-type-a-query-into-the-google-analytics-search-bar">You can also just type a query into the Google Analytics Search Bar.</h3>
<p>Google Analytics has a search bar at the top, and you can just type natural language queries like this one:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/Analytics.png" alt="Image" width="600" height="400" loading="lazy">
<em>The results of a query for "articles by quincy larson past 30 days" shows the number of views each of Quincy's articles has gotten over the past 30 days.</em></p>
<h3 id="heading-which-categories-are-doing-the-best"><strong>Which categories are doing the best?</strong></h3>
<p>This is a trickier one. There are a lot of questions we may be able to answer with the basic reports like we did with Author, such as “out of all of the JavaScript posts, what has the most traffic?”, but maybe we want to know generally what category is the most popular on the site.</p>
<p>To do this we need to get our hands dirty with Custom Reports. This is too advanced to try to tackle in this post, but <a target="_blank" href="https://support.google.com/analytics/answer/1151300?hl=en">Google does a great job at outlining it in detail</a>.</p>
<p>For now, I’ve done you a favor and set up a report that you can easily import to your account and use right away. So first thing’s first, let’s import the report: <a target="_blank" href="https://analytics.google.com/analytics/web/template?uid=4fHol2S_TZqcQACAwfcmfg">https://analytics.google.com/analytics/web/template?uid=4fHol2S_TZqcQACAwfcmfg</a></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-59.png" alt="Image" width="600" height="400" loading="lazy">
<em>Importing a Custom Report in Google Analytics</em></p>
<p>Here you should see a screen like the above that asks us 2 things: where should we apply the report and what do we want to call it? If you’re an author of freecodecamp.org with access to GA and want to view this, you would select the All Web Site Data view under the freeCodeCamp News property.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-60.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting a Property and View when importing a Custom Report in Google Analytics</em></p>
<p>Once selected, name the report what you’d like, such as “Top Primary Categories”, and click Create.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-61.png" alt="Image" width="600" height="400" loading="lazy">
<em>Custom Report showing top Primary Categories in Google Analytics</em></p>
<p>After it’s done, you’ll then land on the newly imported custom report where you can immediately see the most popular categories on the site, which for August is JavaScript!</p>
<h2 id="heading-breakdown"><strong>Breakdown</strong></h2>
<p>This was a lot!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/09/galaxy-quest-alan-rickman-tired.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Alan Rickman in Galaxy Quest sinking in chair</em></p>
<p>But this is just the tip of the data iceberg. Even with just the above, you can see there’s a lot going on and a lot of configuration to make the most out of Google Analytics for your specific needs.</p>
<p>If this interests you, I encourage you to do some research on your own, <a target="_blank" href="https://support.google.com/analytics/answer/1009714?hl=en">add a new view</a> (particularly <a target="_blank" href="https://www.e-nor.com/blog/google-analytics/best-practices-views-google-analytics">a Test View</a> to play around with), and get your hands dirty poking around the different reports. Otherwise, keep an eye out for more of my GA posts covering advanced installation and deeper insights.</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/09/making-sense-of-google-analytics-and-the-traffic-to-your-website">https://www.colbyfayock.com/2019/09/making-sense-of-google-analytics-and-the-traffic-to-your-website</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Top Web Development trends to look out for in 2019 ]]>
                </title>
                <description>
                    <![CDATA[ By Mrudul Shah Do you know that nearly 200 websites are pushed out every minute? Sounds astonishing right? But it is a fact and that’s why it is important that every entrepreneur and developer know about the current web development trends. There are ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/top-web-development-trends-to-look-out-for-in-2019-4f6a03007f22/</link>
                <guid isPermaLink="false">66c36384b737bb2ce70731f5</guid>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 02 Apr 2019 16:21:10 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*WI8ksXTqedgXkHbEnaQYXw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Mrudul Shah</p>
<p>Do you know that nearly 200 websites are pushed out every minute? Sounds astonishing right? But it is a fact and that’s why it is important that every entrepreneur and developer know about the current web development trends.</p>
<p>There are a total of 200 million active websites present out there, while the combined count of total inactive and active sites will be ten times more…</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
