<?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[ front end - 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[ front end - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 09 May 2026 19:40:33 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/front-end/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Node.js Server-Side JavaScript – What is Node Used For? ]]>
                </title>
                <description>
                    <![CDATA[ The release of Node.js in 2009 by Ryan Dahl increased the scope of what developers could do with JavaScript. Prior to that, you could only use JavaScript on the client side (the browser) or frontend of web applications. With Node.js, developers can c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/node-js-server-side-javascript-what-is-node-used-for/</link>
                <guid isPermaLink="false">66b0a32a7cd8dca6718a224f</guid>
                
                    <category>
                        <![CDATA[ Back end development  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ihechikara Abba ]]>
                </dc:creator>
                <pubDate>Tue, 27 Sep 2022 21:34:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/christina-wocintechchat-com-glRqyWJgUeY-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The release of Node.js in 2009 by Ryan Dahl increased the scope of what developers could do with JavaScript. Prior to that, you could only use JavaScript on the client side (the browser) or frontend of web applications.</p>
<p>With Node.js, developers can create server side applications, command line tools, and more. </p>
<p>This article is not a crash course on how to use Node.js (you'll find resources for that in the last section of this article). Rather, it's an introduction to what Node.js is, its features, and what it is used for. </p>
<h2 id="heading-what-is-nodejs">What is Node.js?</h2>
<p>Node.js is an open source JavaScript runtime environment that lets developers run JavaScript code on the server.</p>
<p>If that's too complex for you to understand then you should think of it this way: Node.js is JavaScript that runs outside the browser — on the server. </p>
<p>Note that Node.js is not a programming language - it's a tool.</p>
<h2 id="heading-what-is-so-special-about-nodejs">What Is So Special About Node.js?</h2>
<p>In this section, we'll discuss some of the features that make Node.js cool to use. </p>
<p>The aim is not to compare Node.js to other backend technologies, but to help you understand some of its functionalities. </p>
<h3 id="heading-single-threaded-and-asynchronous">Single Threaded and Asynchronous</h3>
<p>Node.js is fast at executing tasks (receiving requests and sending back responses) because of its single threaded and asynchronous nature. </p>
<p>Let's explain some of the terms above. </p>
<p>By single threaded, this means that Node.js has a single source for handling requests. Multiple threaded backend technologies allocate a new thread for every new request. </p>
<p>You can think of a thread as someone who renders a service to multiple people. A very popular real life example would be a restaurant. We'll explain this example further along with the asynchronous part of Node.js. </p>
<p>Node.js is asynchronous because it can handle multiple requests simultaneously. Let's get back to the restaurant example.</p>
<p>A customer gets to a restaurant and sits down waiting for a server. The server gets to the customer's table and takes their order. The order is then taken to the kitchen. </p>
<p>But the server doesn't wait for the order to be ready before proceeding to the next customer.  They'll return with what the customer ordered for when its ready – in the meantime, the server proceeds to the next customer and repeats the same process. </p>
<p>The example above is similar to how Node.js works under the hood. It is able to process multiple requests using a single thread asynchronously (without waiting for one request's completion before moving to the next). </p>
<p>So when the response for a request is ready, it is sent back to the client. </p>
<p>The single threaded and asynchronous nature of Node.js makes it very fast and ideal for building data-intensive and real-time applications. </p>
<h3 id="heading-javascript-everywhere">JavaScript Everywhere</h3>
<p>Another advantage of using Node.js as a web developer is the possibility of using JavaScript on the frontend and backend of your web app. </p>
<p>Before the release of Node.js, web developers had to learn a different programming language to build the backend of their web apps. </p>
<p>Of course, some developers still use different languages for their backend but Node.js makes it easy to use just one language — JavaScript – if you want. </p>
<h3 id="heading-fast-execution-time">Fast Execution Time</h3>
<p>Node.js is built on Google's V8 JavaScript engine which has a very high performance. This lets Node execute requests quickly. </p>
<h3 id="heading-cross-platform-compatibility">Cross Platform Compatibility</h3>
<p>Node.js supports many major platforms. So you can write your code and it will run on Windows, MacOS, LINUX, UNIX and even some mobile devices. </p>
<h2 id="heading-what-is-node-used-for">What is Node Used For?</h2>
<p>Here are some of the cool things you can do with Node.js:</p>
<ul>
<li>Create HTTP web servers. </li>
<li>Generate web pages dynamically. </li>
<li>Collect and send form data to a database. </li>
<li>Create, read, update, and delete data stored in a database. </li>
<li>Create APIs. </li>
<li>Build command line tools. </li>
<li>Read, write, move, delete, and open/close files on a server. </li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>In this article, we talked about Node.js. We first had a look at what it really is. </p>
<p>We then talked about some the features that make Node.js stand out.</p>
<p>Lastly, we saw a list of how you can use Node.js.</p>
<h3 id="heading-how-to-learn-nodejs">How to Learn Node.js</h3>
<p>Now that you've had a brief introduction to what Node.js is, its features, and what it is used for, here are some resources that you can use to learn how to use Node.js:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/back-end-development-and-apis/">freeCodeCamp's Back End Development and APIs certification</a>. You'll learn how to write back end apps with Node.js and npm. You'll also build web applications with the Express framework, along with MongoDB and the Mongoose library.</li>
<li><a target="_blank" href="https://youtu.be/Oe421EPjeBE">An 8-hour course on the freeCodeCamp.org YouTube channel</a> that'll teach you Node.js and Express. </li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=qwfE7fSVaZM&amp;list=RDCMUC8butISFwT-Wl7EV0hUK0BQ&amp;index=2">A 10-hour project based course on the freeCodeCamp.org YouTube channel</a>. You'll build four projects from the knowledge gained from the 8-hour course above. </li>
</ul>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Become a Front End Developer – Front End Web Dev Skills ]]>
                </title>
                <description>
                    <![CDATA[ Some of the highest-paid professionals in the world are front-end developers. They use their knowledge and talents to design appealing and user-friendly websites. Front-end developers do not need a degree or a school certificate to work. Rather, they... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-become-a-frontend-developer/</link>
                <guid isPermaLink="false">66d45f864a7504b7409c3429</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Joel Olawanle ]]>
                </dc:creator>
                <pubDate>Fri, 10 Jun 2022 20:16:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/06/cover-template--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Some of the highest-paid professionals in the world are front-end developers. They use their knowledge and talents to design appealing and user-friendly websites.</p>
<p>Front-end developers do not need a degree or a school certificate to work. Rather, they must understand the fundamentals of front-end development, programming languages, and front-end development frameworks.</p>
<p>In this guide, you will learn how to become a front end developer by first understanding what front end development entails, the technical and soft skills required, the languages and frameworks available, and some steps to get started.</p>
<p>A front end developer in the United States may earn an average of $86,178 per year, according to <a target="_blank" href="https://www.glassdoor.co.in/Salaries/us-front-end-developer-salary-SRCH_IL.0,2_IN1_KO3,22.htm">Glassdoor</a>. According to <a target="_blank" href="https://www.payscale.com/research/US/Job=Front_End_Developer_%2F_Engineer/Salary">Payscale</a>, a "typical" front-end developer can earn an annual income of $71,350.</p>
<p>If you're new to the tech industry, you might be confused about what front end means, as well as other aspects of web development like back end and full stack, so we'll start by explaining them.</p>
<h2 id="heading-what-is-front-end">What is front end?</h2>
<p>All the websites we browse, the e-commerce websites we purchase goods from, the blogs we read from, and so on are made user-friendly and aesthetically pleasing by front-end developers.</p>
<p>There are two major aspects of web development to consider when building websites and web applications: the front end and the back end.</p>
<p>Front-end development is concerned with the front end of any web application, as the name implies. This is what the user sees and interacts with by performing operations such as clicking a button, scrolling through a page, filling out a form, and so on. This is the client-side functionality of a web application.</p>
<p>Back end refers to the events that occur behind the scenes, such as infrastructure, database connection and communication, and so on. Full stack refers to a combination of front end and back end.</p>
<h2 id="heading-what-does-a-front-end-developer-do">What Does a Front-end Developer Do?</h2>
<p>We just discussed the various aspects of web development, front and, back end, and full stack. And to go along with that we also have different types of developers based on which aspects of web development they are proficient in. So we have front-end developers, back-end developers, and full-stack developers.</p>
<p>A front-end developer is a professional who is in charge of creating the user interface and user experience (UI/UX) that users interact with in order to access the application in question. They are problem solvers who use programming languages, tools, creativity, and experience to create a website or application that solves a user's problem and looks good.</p>
<p>As previously stated, a back-end developer is responsible for everything related to the backend, including logic, database communication, and much more.</p>
<p>Finally, full-stack developers are those who understand both front-end and back-end development, allowing them to start and finish a project on their own.</p>
<p>In a professional setting or standard company, there is usually a UI/UX designer(s) who designs how the interface will look and what they want the user's experience to be.</p>
<p>Then they'll passes their design on to the front-end and back-end developers, who now work on the implementation so the app they've designed works on the web. The front-end developer will recreate the design by writing the program in HTML, CSS, and JavaScript.</p>
<h2 id="heading-how-to-become-a-front-end-developer">How to Become a Front-End Developer</h2>
<p>So far, we've discussed what front end means and who a front-end developer is. Now, let's look at some of the major requirements/skills required before you can call yourself a frontend developer.</p>
<p>It is important to understand that you do not need to know everything before working as a front-end developer, but the fundamentals, such as HTML, CSS, and JavaScript, are always essential.</p>
<h3 id="heading-1-learn-html-css-and-javascript">1. Learn HTML, CSS, and JavaScript</h3>
<p>When you look at a site on the web, the three most important things that make up what you see on the web are HTML, CSS, and JavaScript. So these are the first three things to learn as the foundation for becoming a front-end developer.</p>
<p>They are the building blocks for web and app development, so you must learn if you want to get into web dev. Fortunately, there are numerous online resources available to assist you in learning and practicing them.</p>
<h4 id="heading-what-is-html">What is HTML?</h4>
<p>HTML stands for Hyper Text Markup Language, it is the skeleton of all web pages and applications as thier most basic building block. You use HTML to structure your page into elements such as paragraphs, sections, headings, navigation bars, and so on.</p>
<p>HTML provides structure to the content appearing on a website, such as images, text, or videos. A page with just HTML is very basic and unappealing, and it will need CSS styling to make it presentable.</p>
<p>HTML is frequently the first language that developers learn, and it is essential for front-end development work. Do you want to know more about HTML? Begin with <a target="_blank" href="https://www.freecodecamp.org/learn/responsive-web-design/">freeCodeCamp's Responsive Web Design certification</a> and <a target="_blank" href="https://www.freecodecamp.org/news/html-crash-course/">Beau Carnes' brand new full HTML course</a>.</p>
<h4 id="heading-what-is-css">What is CSS?</h4>
<p>CSS is an abbreviation for Cascading Style Sheets, and you use it to enhance the appearance of a web page by adding CSS styles. These styles make your website more appealing and enjoyable to view and use for the end user.</p>
<p>Do you want to know more about CSS? To get started, check out the <a target="_blank" href="https://www.freecodecamp.org/learn/responsive-web-design/">second part of freeCodeCamp's Responsive Web Design certification</a>.</p>
<h4 id="heading-what-is-javascript">What is JavaScript?</h4>
<p>HTML is a markup language, CSS is a style sheet, and then we have JavaScript, the third building block. JavaScript is a programming language that allows you to make your web pages more interactive. This can include animations, dynamic styling, effects/behaviors when buttons are clicked, game motion, and so on.</p>
<p>If you want to learn JavaScript, look into freeCodeCamp's <a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/">JavaScript Algorithms and Data Structures certification</a>. You can also supplement your learning with this excellent <a target="_blank" href="https://www.freecodecamp.org/news/learn-javascript-full-course/">Intro to JS course</a>.</p>
<h3 id="heading-2-practice-coding">2. Practice Coding</h3>
<p>There is a popular idiom that says “Practice makes perfect”. This means that you'll become better at something if you do it often.</p>
<p>If you want to become a professional front-end developer, you have to practice consistently. This will help you learn the concepts thoroughly (and not just on the surface). The more you practice, the more (and better) you'll understand concepts.</p>
<h3 id="heading-3-enhance-your-skills">3. Enhance Your Skills</h3>
<p>"Learn constantly, there is always one more thing to learn!" said Steve Jobs. This holds true in all aspects of life, including programming and front-end development.</p>
<p>As new technologies, tools, syntax, and approaches are introduced, it is always best to stay up to date with new technology trends and avoid falling behind.</p>
<p>This will help you grow your skills as a front-end developer, and you can always stay in the loop by joining and interacting with active developer communities. There are many communities out there, such as the freeCodeCamp developer community and all of the other local communities that surround everyone of us including you.</p>
<h3 id="heading-4-learn-the-command-line-and-version-control">4. Learn the Command Line and Version Control</h3>
<p>As a frontend developer, you should understand how the command line works because it allows you to access operating system functions through a text interface. Many professionals prefer CLIs for their speed and performance when installing libraries and frameworks.</p>
<p>Front-end developers should also be familiar with version control systems such as Git, which is the most widely used. When coding, you'll frequently want to trace your coding history and other information.</p>
<p>Version control makes this much easier because it allows you and your team to efficiently communicate and manage (track) all changes made to the source code. It also gives you information such as who made the changes and what changes were made.</p>
<h3 id="heading-5-understand-application-program-interfaces-apis">5. Understand Application Program Interfaces (APIs)</h3>
<p>As a professional frontend developer, you should be familiar with APIs and how to consume and manipulate them. This is critical for communicating with backend logics and databases.</p>
<p>To interact with APIs in JavaScript, you’ll mostly use the browser's Fetch API or the Axios library. This article explains <a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-api-calls-with-fetch/">how to use the Fetch API in JavaScript</a>.</p>
<h3 id="heading-6-learn-and-understand-javascriptcss-libraries">6. Learn and Understand JavaScript/CSS Libraries</h3>
<p>Today, there are numerous JavaScript libraries available, all of which aim to make web application development easier. These are pre-written JavaScript scripts that make developing JavaScript-based applications easier.</p>
<p>There are have a lot of them, but it's best to pick one and learn it thoroughly, such as React, Vue, or Angular (three of the most popular). You can check out <a target="_blank" href="https://www.freecodecamp.org/learn/front-end-development-libraries/">freeCodeCamp’s frontend libraries development certification course</a> to learn more.</p>
<p>There are also have some style libraries that make styling your web pages simple, such as Bootstrap, Sass/Scss, Tailwind, and so on.</p>
<h3 id="heading-7-build-an-online-portfolio">7. Build an online portfolio</h3>
<p>Building your portfolio is an easy way to demonstrate your expertise as a front-end developer.</p>
<p>If you're just starting out as a front-end developer, you don't have to have every piece of your portfolio be a client project. You can take charge and be inventive. Make use of new tools and libraries to create something spectacular. As your career progresses, you will be able to highlight more projects on which you have worked.</p>
<p>You can also look through the portfolios of your fellow front-end developers to see what you like and dislike. Then, knowing what you want to show the world, create your own website.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/create-a-portfolio-website-using-html-css-javascript/">Here's a fun course</a> that will help you build your own portfolio site with HTML, CSS, and JavaScript – so you can practice those web dev skills.</p>
<p>You can also have friends and members of the community critique and test your site to ensure that everything looks good. Don't forget that all of the words on your website should be assisting you in landing a great job. You don't want it to be too long or too boring.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/level-up-developer-portfolio/">Here's are some tips</a> that'll help you level up your developer portfolio to really make it stand out.</p>
<h3 id="heading-8-cultivate-your-soft-skills">8. Cultivate your soft skills</h3>
<p>Front-end developers must be effective <strong>communicators</strong> (written and verbal) because they must interact with both the technical team and the client.</p>
<p>They must also be excellent communicators within their code, as it is critical to take the time to comment and write appropriate documentation within your code so that you and others can easily understand it even after a long time.</p>
<p>Front-end developers should also have good <strong>attention to detail</strong> and be meticulous in all aspects of their work. They must have a keen eye and be able to catch small errors or inconsistencies when creating web pages.</p>
<p>And front-end developers must be <strong>lifelong learners</strong>, because websites are evolving and expectations for responsiveness, accessibility, and appearance are always changing. Front-end engineers must stay as current as they're able and will almost certainly need to learn new code languages or libraries over time.</p>
<h3 id="heading-9-start-applying-for-internships-or-jobs-you-want">9. Start applying for internships or jobs you want</h3>
<p>Once you have gained proper knowledge of frontend by learning necessary skills and <a target="_blank" href="https://www.freecodecamp.org/news/how-to-write-a-developer-resume-recruiters-will-read/">building a simple résumé</a>, you can now begin to search for front-end job opportunities.</p>
<p>Check out their requirements to see what other areas you need to improve in as a front-end developer.</p>
<p>Finally, always apply for jobs, and never be afraid to apply. This will give you some experience to help you learn how companies hire and what it takes to be hired.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we've learned what a front-end developer is and what it takes to become one.</p>
<p>We've also learned that becoming a front-end developer without a degree is not only possible, but also attainable.</p>
<p>One final question most people have is how long it takes to become a front-end developer. Well, the length of time it takes is entirely dependent on your learning pace and prior knowledge.</p>
<p>Just remember – don't compare yourself or your learning pace to that of others as you learn. Set aside some time each week or day to learn, do your best to stick to it, and then rejoice.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use PyScript – A Python Frontend Framework ]]>
                </title>
                <description>
                    <![CDATA[ By Ifihanagbara Olusheye Python has grown in popularity immensely in recent years. It has a wide range of applications, from its most popular use in Artificial Intelligence, to Data Science, Robotics, and Scripting. In the web development field, Pyth... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/pyscript-python-front-end-framework/</link>
                <guid isPermaLink="false">66d45f333a8352b6c5a2aa61</guid>
                
                    <category>
                        <![CDATA[ framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 26 May 2022 15:37:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-05-26-at-13.28.49.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ifihanagbara Olusheye</p>
<p>Python has grown in popularity immensely in recent years. It has a wide range of applications, from its most popular use in Artificial Intelligence, to Data Science, Robotics, and Scripting.</p>
<p>In the web development field, Python is used mainly on the backend with frameworks such as Django and Flask.</p>
<p>Before now, Python didn't have much support on the front-end side like other languages such as JavaScript. But thankfully, Python developers have built some libraries (such as <a target="_blank" href="https://brython.info/">Brython</a>) to support their favourite language on the web.</p>
<p>And this year, during the <a target="_blank" href="https://youtube.com/playlist?list=PL2Uw4_HvXqvYeXy8ab7iRHjA-9HiYhRQl">PyCon 2022 conference</a>, Anaconda announced a framework named PyScript that allows you to use Python on the web using standard HTML.</p>
<p>You can check out this tweet about the launch:</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/anacondainc/status/1520447158603890691?s=20&amp;t=K-hrRhY9RwRaIkD-45acTQ"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p> </p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>You'll need the following tools and knowledge to code along with this article:</p>
<ul>
<li><p>A text editor or IDE of your choice.</p>
</li>
<li><p>Knowledge of Python.</p>
</li>
<li><p>Knowledge of HTML.</p>
</li>
<li><p>A browser (Google Chrome is the recommended browser for PyScript).</p>
</li>
</ul>
<h2 id="heading-what-is-pyscript">What is PyScript?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-05-22-at-18.29.40.png" alt="Image from PyScript's website." width="600" height="400" loading="lazy"></p>
<p><em>Source:</em> <a target="_blank" href="https://pyscript.net/"><em>PyScript official website</em></a></p>
<p>PyScript is a Python front-end framework that enables users to construct Python programs using an HTML interface in the browser.</p>
<p>It was developed using the power of <a target="_blank" href="https://emscripten.org/">Emscripten</a>, <a target="_blank" href="https://pyodide.org/en/stable/">Pyodide</a>, <a target="_blank" href="https://webassembly.org/">WASM</a>, and other modern web technologies to provide the following abilities in line with its goals:</p>
<ul>
<li><p>To provide a simplistic and clean API.</p>
</li>
<li><p>To provide a system of pluggable and extensible components.</p>
</li>
<li><p>To support and extend standard HTML to read opinionated and dependable custom components in order to reach the mission “Programming for the 99%.”</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-05-26-at-11.27.01.png" alt="An image showing what PyScript is built on." width="600" height="400" loading="lazy"></p>
<p><em>Source:</em> <a target="_blank" href="https://www.anaconda.com/blog/pyscript-python-in-the-browser"><em>Anaconda Blog</em></a></p>
<p>In the last couple of decades, Python and advanced UI languages like modern HTML, CSS, and JavaScript have not worked in collaboration. Python lacked a simple mechanism to create appealing UIs for simply packaging and deploying apps, while current HTML, CSS, and JavaScript can have a steep learning curve.</p>
<p>Allowing Python to utilize HTML, CSS, and JavaScript conventions solves not only those two problems but also those related to web application development, packaging, distribution, and deployment.</p>
<p>PyScript isn't meant to take the role of JavaScript in the browser, though – rather, it's meant to give Python developers, particularly data scientists, more flexibility and power.</p>
<h2 id="heading-why-pyscript">Why PyScript?</h2>
<p>PyScript gives you a programming language with consistent styling conventions, more expressiveness, and ease of learning by providing the following:</p>
<ul>
<li><p><strong>Support on the browser:</strong> PyScript enables support for Python and hosting without the need for servers or configuration.</p>
</li>
<li><p><strong>Interoperability:</strong> Programs can communicate bi-directionally between Python and JavaScript objects and namespaces.</p>
</li>
<li><p><strong>Ecosystem support:</strong> PyScript allows the use of popular Python packages such as Pandas, NumPy, and many more.</p>
</li>
<li><p><strong>Framework flexibility:</strong> PyScript is a flexible framework that developers can build on to create extensible components directly in Python easily.</p>
</li>
<li><p><strong>Environment Management:</strong> PyScript allows developers to define the files and packages to include in their page code to run.</p>
</li>
<li><p><strong>UI Development:</strong> With PyScript, developers can easily build with available UI components such as buttons and containers, and many more.</p>
</li>
</ul>
<h2 id="heading-how-to-get-started-with-pyscript">How to Get Started with PyScript</h2>
<p>PyScript is fairly easy and straightforward to learn. To get started, you can either follow the instructions on the <a target="_blank" href="https://pyscript.net/">website</a> or download the <a target="_blank" href="https://github.com/pyscript/pyscript/archive/refs/heads/main.zip">.zip</a> file.</p>
<p>In this article, we'll be using and learning how to use PyScript via the <a target="_blank" href="https://pyscript.net/">website</a>. You can do this by linking the components in your HTML file. Let’s print our first “Hello World” with PyScript.</p>
<h3 id="heading-create-an-html-file">Create an HTML file</h3>
<p>To begin, you'll need to create an HTML file to display text on your browser using the text editor/IDE of your choice.</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">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span>
          <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"ie=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Title: PyScript<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>

<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>
<h3 id="heading-link-pyscript">Link PyScript</h3>
<p>After creating the HTML file, we'll need to link PyScript in your HTML file to have access to the PyScript interface. This will be placed in the <code>&lt;head&gt;</code> tag.</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">"https://pyscript.net/alpha/pyscript.css"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">defer</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://pyscript.net/alpha/pyscript.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-print-to-browser">Print to browser</h3>
<p>Now that you've linked PyScript to the HTML file, you can print your “Hello World”.</p>
<p>You can do this with the <code>&lt;py-script&gt;</code> tag. The <code>&lt;py-script&gt;</code> tag allows you to run multi-line Python programs and have them printed on the browser page. Place the tag in between the <code>&lt;body&gt;</code> tags.</p>
<pre><code class="lang-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">py-script</span>&gt;</span> print("Hello, World!") <span class="hljs-tag">&lt;/<span class="hljs-name">py-script</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>The full code for the HTML file is below:</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">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span>
          <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"ie=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Title: PyScript<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">py-script</span>&gt;</span> print("Hello, World!") <span class="hljs-tag">&lt;/<span class="hljs-name">py-script</span>&gt;</span>
<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>On your browser, you should see this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-05-23-at-18.19.48.png" alt="Image of the &quot;Hello, World&quot; on browser." width="600" height="400" loading="lazy"></p>
<p><strong>Tip:</strong> If you're using the VSCode editor, you can use the Live Server add-on in <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">VSCode</a> to reload the page as you update the HTML file.</p>
<h2 id="heading-more-operations-with-pyscript">More Operations with PyScript</h2>
<p>There are more operations you can perform with the PyScript framework. Let's look at some of them now.</p>
<h3 id="heading-attach-labels-to-labeled-elements">Attach labels to labeled elements</h3>
<p>While using PyScript, you might want to pass variables from your Python code to HTML. You can do this with the <code>write</code> method from the <code>pyscript</code> module within the <code>&lt;pyscript&gt;</code> tag. Using the <code>id</code> attribute , you get to pass strings displayed as regular text.</p>
<p>The write method accepts two variables: the <code>id</code> value and the variable that will be provided.</p>
<pre><code class="lang-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
      <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">"https://pyscript.net/alpha/pyscript.css"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">defer</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://pyscript.net/alpha/pyscript.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Today is <span class="hljs-tag">&lt;<span class="hljs-name">u</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'today'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">u</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">py-script</span>&gt;</span>
import datetime as dt
pyscript.write('today', dt.date.today().strftime('%A %B %d, %Y'))
    <span class="hljs-tag">&lt;/<span class="hljs-name">py-script</span>&gt;</span>
  <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>And the output becomes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-05-24-at-11.07.18.png" alt="Image showing the output of a date." width="600" height="400" loading="lazy"></p>
<h3 id="heading-run-repl-in-the-browser">Run REPL in the browser</h3>
<p>PyScript provides an interface for running Python code in browsers.</p>
<p>To be able to do this, PyScript uses the <code>&lt;py-repl&gt;</code> tag. The <code>&lt;py-repl&gt;</code> tag adds a REPL component to the page, which acts as a code editor and allows you to write executable code inline.</p>
<pre><code class="lang-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <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">"https://pyscript.net/alpha/pyscript.css"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">defer</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://pyscript.net/alpha/pyscript.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">py-repl</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-repl"</span> <span class="hljs-attr">auto-generate</span>=<span class="hljs-string">true</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">py-repl</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Trying it out in browser (preferably Chrome), you should get this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-05-24-at-16.14.34.png" alt="Python's REPL in browser." width="600" height="400" loading="lazy"></p>
<h3 id="heading-import-files-modules-and-libraries">Import Files, Modules, and Libraries</h3>
<p>One of the functions PyScript provides is flexibility. In PyScript you can import local files, inbuilt modules, or third-party libraries. This process uses the <code>&lt;py-env&gt;</code> tag. This tag is for declaring the dependencies needed.</p>
<p>For local Python files on your system, you can place the code in a <code>.py</code> file and the paths to local modules are provided in the paths: key in the <code>&lt;py-env&gt;</code> tag.</p>
<p>Let’s create a Python file <code>example.py</code> to contain some functions:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> randint

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_two_numbers</span>(<span class="hljs-params">x, y</span>):</span>
    <span class="hljs-keyword">return</span> x + y

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generate_random_number</span>():</span>
    x = randint(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>)
    <span class="hljs-keyword">return</span> x
</code></pre>
<p>Then the Python file will be imported into the HTML with the <code>&lt;py-env&gt;</code> tag. You should place this tag in the the <code>&lt;head&gt;</code> tag, above the <code>&lt;body&gt;</code> tag.</p>
<pre><code class="lang-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
      <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">"https://pyscript.net/alpha/pyscript.css"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">defer</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://pyscript.net/alpha/pyscript.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">py-env</span>&gt;</span>
        - paths:
          - /example.py
      <span class="hljs-tag">&lt;/<span class="hljs-name">py-env</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Let's print random numbers<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span>Doe's lucky number is <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"lucky"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">py-script</span>&gt;</span>
      from example import generate_random_number
      pyscript.write('lucky', generate_random_number())
    <span class="hljs-tag">&lt;/<span class="hljs-name">py-script</span>&gt;</span>
  <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>This will return:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-05-24-at-23.20.31.png" alt="Printing out random numbers with Python." width="600" height="400" loading="lazy"></p>
<p>For third-party libraries that are not part of the standard library, PyScript supports them.</p>
<pre><code class="lang-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
      <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">"https://pyscript.net/alpha/pyscript.css"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">defer</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://pyscript.net/alpha/pyscript.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">py-env</span>&gt;</span>
            - numpy
            - requests
      <span class="hljs-tag">&lt;/<span class="hljs-name">py-env</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">py-script</span>&gt;</span>
    import numpy as np
    import requests
    <span class="hljs-tag">&lt;/<span class="hljs-name">py-script</span>&gt;</span>
  <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>
<h3 id="heading-configure-metadata">Configure metadata</h3>
<p>You can set and configure general metadata about your PyScript application in YAML format using the <code>&lt;py config&gt;</code> tag. You can use this tag in this format:</p>
<pre><code class="lang-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">py-config</span>&gt;</span>
  - autoclose_loader: false
  - runtimes:
    -
      src: "https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js"
      name: pyodide-0.20
      lang: python
<span class="hljs-tag">&lt;/<span class="hljs-name">py-config</span>&gt;</span>
</code></pre>
<p>These are the optional values that the <code>&lt;py-config&gt;</code> tag provides. They include:</p>
<ul>
<li><p><strong>autoclose_loader (boolean):</strong> If this is set to false, PyScript will not close the loading splash screen.</p>
</li>
<li><p><strong>name (string):</strong> Name of the user application.</p>
</li>
<li><p><strong>version (string):</strong> Version of the user application.</p>
</li>
<li><p><strong>runtimes (List of Runtimes):</strong> List of runtime configurations which would have the following fields: src, name, and lang.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you learned what PyScript is all about and how to use it in HTML files to run Python code on the browser. You also learned about the various operations/functionalities you can do with PyScript.</p>
<p>With PyScript, it’s easier to run and perform Python operations on the web, as this wasn’t easy before. This is a great tool for anyone who's looking forward to using Python on the web.</p>
<p>PyScript is still in its early stages and under heavy development. It is still in its alpha stage and faces known issues like the load time which can affect usability (some other operations can’t be shown at the time of this writing due to performance issues). So you shouldn't use it in production yet as there will likely be a lot of breaking changes.</p>
<h2 id="heading-references">References</h2>
<ul>
<li><p><a target="_blank" href="https://pyscript.net/">The PyScript official website</a>.</p>
</li>
<li><p><a target="_blank" href="https://www.anaconda.com/blog/pyscript-python-in-the-browser">Anaconda blog</a>.</p>
</li>
<li><p><a target="_blank" href="https://github.com/pyscript/pyscript">PyScript source code</a>.</p>
</li>
<li><p><a target="_blank" href="https://github.com/pyscript/pyscript/blob/main/docs/tutorials/getting-started.md">Guide on getting started with PyScript</a>.</p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Front End Development Trends to Watch in 2022 ]]>
                </title>
                <description>
                    <![CDATA[ By Adam Zaczek Front end development hasn't always gotten the respect it deserves compared to back end development. Many engineers used to look down on JavaScript. But times have changed. Web applications are growing rapidly, mainly due to the develo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/front-end-development-trends/</link>
                <guid isPermaLink="false">66d45d5ad7a4e35e38434922</guid>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 08 Feb 2022 19:13:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/02/shutterstock_1610721214-min.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adam Zaczek</p>
<p>Front end development hasn't always gotten the respect it deserves compared to back end development.</p>
<p>Many engineers used to look down on JavaScript. But times have changed. Web applications are growing rapidly, mainly due to the development of open-source tools.</p>
<p>This development has moved us farther away from jQuery and has made almost every tech company use the latest JavaScript and tools like Eslint, Babel, and Webpack.</p>
<p>Nowadays, the front end is moving at a speed that makes it hard to follow.</p>
<p>This post is all about catching up with the directions of this development area in 2022. Perhaps you will find something for yourself in these trends.</p>
<h2 id="heading-svelte-is-gaining-popularity">Svelte is gaining popularity</h2>
<p>Svelte is a relatively new tool, which in theory started much too late to be able to have a chance against React, Vue, and Angular. But it's steadily gaining popularity at an unprecedented pace.</p>
<p>In 2021, StackOverflow users <a target="_blank" href="https://insights.stackoverflow.com/survey/2021#technology-most-loved-dreaded-and-wanted">announced it as the most loved front-end framework</a>.</p>
<p>But Svelte is more than that. It is a compiler that builds an optimized front end.<br>Svelte is not imported into the application like other popular frameworks. Instead, code written in Svelte gets compiled into pure JavaScript. This allows Svelte to win in terms of speed against frameworks such as React or Vue.  </p>
<p>Using the Svelte framework is very easy. Here is an example of how you'd use state + forms:</p>
<pre><code class="lang-JavaScript">Using the framework is very easy. Here is an example <span class="hljs-keyword">of</span> using state + forms.
&lt;script&gt;
 <span class="hljs-keyword">let</span> a = <span class="hljs-number">1</span>;
 <span class="hljs-keyword">let</span> b = <span class="hljs-number">2</span>;
&lt;/script&gt;

&lt;label&gt;
 &lt;input type=number bind:value={a} min=0 max=10&gt;
 &lt;input type=range bind:value={a} min=0 max=10&gt;
&lt;/label&gt;

&lt;label&gt;
 &lt;input type=number bind:value={b} min=0 max=10&gt;
 &lt;input type=range bind:value={b} min=0 max=10&gt;
&lt;/label&gt;

&lt;p&gt;{a} + {b} = {a + b}&lt;/p&gt;
</code></pre>
<p>Simple as that! Notice three things here:</p>
<ol>
<li>Forms are handled in a simple, elegant way, like in the old days, before the SPA frameworks. There is no need to attach onChange props to the inputs.</li>
<li>Markup and logic lives side by side, encapsulating the logic and a visible layer.</li>
<li>State is easy to manage.</li>
</ol>
<p>No wonder the framework is gaining traction in the community. It is only a matter of time before new popular platforms are created in Svelte.</p>
<h2 id="heading-react-vue-and-angular-are-here-to-stay">React, Vue, and Angular are here to stay</h2>
<p>I started my adventure with the front end just before the premiere of Angular 2, about six years ago. I can’t count how many times since then I have read that Vue, React, or Angular is dying.</p>
<p>The truth has turned out to be quite different, though. Each of these three frameworks has grown in popularity since its inception.</p>
<p>Here is the chart (<a target="_blank" href="https://www.npmtrends.com/react-vs-vue-vs-@angular/core">Source: Npm Trends</a>). It is worth adding that every sudden drop on the chart is there because of December.</p>
<p><img src="https://lh6.googleusercontent.com/ilDTORi3UIlBJdZXPoQ5u9Y2SQbLdhXeJXLHt_KaRKT-BGKv1WZEYuHnQEDk73ZTfKdUUANCMIHljewTGACDB_6xma8ISwzAV-cU50mj2YJ0L0yAsN_hhF28XRJA9bVRtuVtyCeO" alt="Image" width="600" height="400" loading="lazy">
<em>Angular vs React vs Vue download trends</em></p>
<p>Take a look at the chart above. Notice that Angular has grown in popularity by a factor of over ten. React and Vue grew even faster. All three frameworks support pretty much the same use cases.</p>
<p>This means no matter which of the three frameworks you choose, you can expect it to be used and supported for years to come.</p>
<p>It’s worth noting that React didn't have any significant changes in 2021. Yet the pace of its adaptation is astounding. It is likely because of the ecosystem around the technology. React has the largest selection of libraries and supporting frameworks.</p>
<p>Two examples worth mentioning are Next and Gatsby. The latter is one of the perpetrators of the next trend.</p>
<h2 id="heading-frameworks-need-to-support-both-static-and-dynamic-pages">Frameworks need to support both static and dynamic pages</h2>
<p>Let's establish what static and dynamic pages are in practical terms.</p>
<p>Dynamic pages fetch and process the content when the user opens them. Static pages are pre-defined during the build time. They become separate, generated files on the disc. They can look just the same as dynamic, but the user's browser has less work to do.</p>
<p>If you have a shop, you can have a single dynamic product page, or thousands of static product pages, one for every product.</p>
<p>This means that static pages are more performant for users, but take a lot longer to build.</p>
<p>The reason for abandoning static pages was the popularization of the React and Vue type single-page application (SPA) frameworks. They also restored them to favour.</p>
<p>Dynamic content that SPA's typically generate is much slower than a ready-to-display one written in HTML. The difference is especially big when the page is fetching data from the server. A dynamic page would typically have to download and process such data.</p>
<p>This resulted in giving birth to static pages in SPAs. Gatsby tackled this problem by building a framework and infrastructure for static pages in React.</p>
<p>A website like a blog, portfolio, or even a course platform like freeCodeCamp will be much faster static. Even server-side rendering, as is usually the case with Next.js, does not guarantee better speed (<a target="_blank" href="https://hackernoon.com/gatsby-won-against-nextjs-in-this-heads-up-competition-xa7p3ysc">Source: Sidney Alcantara</a>).</p>
<p>Focus on time to first contentful paint results in a large number of solutions for generating static pages in other frameworks, such as Vue or Svelte.</p>
<p>On the other hand, static pages are hard to scale for millions of pages. If you are building an app with a lot of dynamic content like user profiles, you are probably better off using dynamic pages. Both ways of handling content are here to stay.</p>
<h2 id="heading-platforms-turn-single-developers-into-entire-it-departments">Platforms turn single developers into entire IT departments</h2>
<p>Recent years have brought a flood of platforms that speed up front-end development. This is huge because it allows small teams to move fast. </p>
<p>You can easily implement video using <a target="_blank" href="https://www.twilio.com/">Twilio</a> or <a target="_blank" href="https://www.agora.io/">Agora.io</a>. You can add authentication in no time using <a target="_blank" href="https://firebase.google.com/docs/auth">Firebase</a>, <a target="_blank" href="https://aws.amazon.com/cognito/">Amazon Cognito</a> or <a target="_blank" href="https://www.okta.com/">Okta</a> (Okta also acquired <a target="_blank" href="https://auth0.com/">Auth0</a>).</p>
<p>Deploying front-end code automatically and globally is especially worth talking about. There are three go-to solutions: Vercel, Gatsby Cloud, and Netlify. They can turn one front-end developer with an GitHub account into the entire DevOps department in 5 minutes.  </p>
<p>At the moment of writing, all three platforms offer a relatively similar average loading times (Sources: <a target="_blank" href="https://bejamas.io/compare/netlify-vs-vercel/">Netlify vs Vercel</a>, <a target="_blank" href="https://bejamas.io/compare/netlify-vs-gatsby-cloud/">Netlify vs Gatsby Cloud</a>).</p>
<p>Gatsby Cloud is React only but makes working with countless static pages almost too easy. If you are building a Gatsby app, it's probably your best bet.</p>
<p>Vercel supports the major frameworks, including server-side ones, like the company founders' own framework, Next.js. If you are working on a server-side rendered app, Vercel will make your life a lot easier.</p>
<p>Netlify focuses on client side frameworks, like pure React and Vue. It offers a wide range of useful tools such as ready-to-use forms, authentication and serverless functions. I believe it is the best choice for the traditional, client side apps.</p>
<p>One underdog worth mentioning is Shuffle.dev. It can create a professional website layout randomly, in seconds. It has a relatively large selection of themes and CSS frameworks and adds new features and content on a weekly basis. At <a target="_blank" href="https://codeally.io/">CodeAlly.io</a>, we use it a lot to speed up prototyping.</p>
<h2 id="heading-front-end-optimization-is-key">Front end optimization is key</h2>
<p>The front end has come full circle in recent years. Light sites turned into heavy platforms with long render times. Some people may still remember when Slack used the developer version of React (<a target="_blank" href="https://twitter.com/pankowecki/status/892294002040594434">Source: Robert Pankowecki</a>). The trend to make SPAs faster has been around for years but is still gaining momentum.</p>
<p>Libraries that negatively impact the performance, like Moment.js, are replaced by their lighter, performant counterparts such as Day.js. Others get refactored to reduce the bundle size. Examples include Material UI and Lodash.</p>
<p>Sentry, the market leader in error logging, only started working on bundle size optimization a few months ago. Throughout the front-end ecosystem, there is a growing emphasis on using lazy loading, rendering the front end on the server-side, or using CSS files instead of styling the application with JavaScript, as was the case with, for example, styled-components.</p>
<p>Tailwind has gained much popularity recently and, in 2022, it will surely remain popular. It handles reducing the application load time like almost no other CSS tool. </p>
<p>That being said, it has a steep learning curve. The Tailwind code is often hard to read. </p>
<p>I highly recommend trying Linaria too. Linaria combines the advantages of styled-components and the speed of using static CSS files. We have been using it for a while at <a target="_blank" href="https://codeally.io/">CodeAlly.io</a> and, the entire front-end team loves this library: <a target="_blank" href="https://github.com/callstack/linaria">https://github.com/callstack/linaria</a>.</p>
<p>Example code in Linaria:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">import</span> { styled } <span class="hljs-keyword">from</span> <span class="hljs-string">'@linaria/react'</span>;
<span class="hljs-keyword">import</span> mainTheme <span class="hljs-keyword">from</span> <span class="hljs-string">'themes/mainThemeV2'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Wrapper = styled.div<span class="hljs-string">`
 display: flex;
 flex-direction: column;
 align-items: center;
 height: 100%;
 width: 30px;
 max-height: 60px;
 border-bottom: 1px solid <span class="hljs-subst">${mainTheme.colors.neutral300}</span>;
 background-color: <span class="hljs-subst">${mainTheme.colors.primary300}</span>;
 border-radius: 8px;
`</span>;
</code></pre>
<p>Notice how you can use JavaScript in styles. It is also possible to reuse styles since they are regular JS constants. The code gets compiled into a CSS file during the build process.</p>
<p>This results in a combination of a great developer experience and a blazing-fast front-end.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>When I was getting started, things were moving much slower. There is a lot of innovation happening and the front end is evolving fast.  </p>
<p>If you want to work in the industry, you might want to check <a target="_blank" href="https://codeally.io/">CodeAlly</a> out. It's a platform I founded with friends where tech companies compete for programmers by inviting them for jobs.</p>
<p>New programmers with little to no experience also get to prove their skills with a built-in VSCode and Docker code challenges.  </p>
<p>I hope this article was fun to read and you’ve found something valuable here. Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Front End Developer – What is Front End Development, Explained in Plain English ]]>
                </title>
                <description>
                    <![CDATA[ If you are new to programming, you might have heard of the term Front End Development. But what does that mean?  In this article, I will explain what Front End Development is, what skills you need to become a Front End Developer, and tips for landing... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/front-end-developer-what-is-front-end-development-explained-in-plain-english/</link>
                <guid isPermaLink="false">66b8d94dce55d3ba4d935991</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jessica Wilkins ]]>
                </dc:creator>
                <pubDate>Mon, 23 Aug 2021 15:30:27 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/christina-wocintechchat-com-uSL0rdRY-Uw-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you are new to programming, you might have heard of the term Front End Development. But what does that mean? </p>
<p>In this article, I will explain what Front End Development is, what skills you need to become a Front End Developer, and tips for landing a job. </p>
<h2 id="heading-what-is-front-end-development">What is Front End Development?</h2>
<p>Everything you see on a website, like buttons, links, animations, and more, were created by a front end web developer. It is the front end developer's job to take the vision and design concept from the client and implement it through code. </p>
<p>Let's take a look at the <a target="_blank" href="https://www.freecodecamp.org/">freeCodeCamp home page</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-21-at-12.10.19-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Everything on the page from the logo to the search bar, buttons, overall layout and how the user interacts with the page was created by a front end developer. Front end developers are in charge of the look and feel of the website. </p>
<p>Front end developers also have to make sure the website looks good on all devices (phones, tablets, and computer screens).</p>
<h2 id="heading-what-skills-do-you-need-to-become-a-front-end-developer">What Skills Do You Need to Become a Front End Developer?</h2>
<p>The three main languages you need to know well are HTML, CSS, and JavaScript. From there you can focus on frameworks, libraries, and other useful tools.  </p>
<h3 id="heading-html">HTML</h3>
<p>HTML stands for HyperText Markup Language. HTML displays the content on the page like buttons, links, headings, paragraphs, and lists. </p>
<p>You should not use HTML for styling. That is what CSS is for. </p>
<p>I would suggest going through the <a target="_blank" href="https://www.freecodecamp.org/learn/responsive-web-design/#basic-html-and-html5">freeCodeCamp HTML challenges</a> to start learning the basics. </p>
<h3 id="heading-css">CSS</h3>
<p>CSS stands for Cascading Style Sheets. CSS is responsible for the style of your web page including colors, layouts, and animations. </p>
<p><a target="_blank" href="https://www.freecodecamp.org/learn/responsive-web-design/">freeCodeCamp's Responsive Web Design Course</a> will teach you the basics of CSS, responsive design and accessibility. Responsive design is essential in creating websites that look good on all devices. </p>
<p>Accessibility is the practice of making sure that everyone can easily use your web sites. You do not want to create web sites that cannot be used by those with assistive technologies like screen readers. </p>
<p>After completing the course, you will be able to starting building small web pages. </p>
<h3 id="heading-javascript">JavaScript</h3>
<p>JavaScript allows users to interact with the web page. Examples of JavaScript can be found in virtually any web page including the freeCodeCamp homepage. </p>
<p>For example, when I click on the Menu button at the top of the page, it will open a dropdown list of options. Every time I click on that button, it will toggle back and forth between opening and closing the Menu. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-21-at-12.45.20-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>JavaScript can be used in online games, web pages, mobile applications and more. </p>
<p>To start learning JavaScript, you can take <a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/">freeCodeCamp's JavaScript Algorithms and Data Structures course</a>. From there, you can start building projects from my <a target="_blank" href="https://www.freecodecamp.org/news/javascript-projects-for-beginners/">40 JavaScript Projects for Beginners</a>. </p>
<h3 id="heading-css-frameworks-libraries-and-preprocessors">CSS Frameworks, Libraries, and Preprocessors</h3>
<p>Once you learn the basics of CSS, then you can start to work with different frameworks and libraries. These tools were created as a way to help speed up the development process.</p>
<p>Frameworks like <a target="_blank" href="https://getbootstrap.com/">Bootstrap</a> and <a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a> allow you to add the catalog of classes to your webpage. As a result, you end up with professional and mobile-friendly designs.   </p>
<p>There are dozens of options on the market and you don't need to learn them all. It's often helpful to look at jobs in your area and see what technologies they're using. Then you can focus on the most common/in-demand skills.</p>
<p>Here is a list of a few options:</p>
<ul>
<li><a target="_blank" href="https://getbootstrap.com/">Bootstrap</a></li>
<li><a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a></li>
<li><a target="_blank" href="https://bulma.io/">Bulma</a></li>
<li><a target="_blank" href="https://materializecss.com/">Materialize</a></li>
<li><a target="_blank" href="https://semantic-ui.com/">Semantic UI</a></li>
</ul>
<p>CSS preprocessors like <a target="_blank" href="https://sass-lang.com/">Sass</a> and <a target="_blank" href="https://lesscss.org/">Less</a>, allow you to add logic and functionality to your CSS. These tools make your CSS clean and easy to work with.  </p>
<h3 id="heading-javascript-libraries-and-frameworks">JavaScript libraries and frameworks</h3>
<p>Just like with the CSS libraries and frameworks, there are many options for JavaScript. </p>
<p>It is not necessary to learn them all. Same as above, research job postings in your area to see what libraries and frameworks are being used. </p>
<p>Here are some popular options:</p>
<ul>
<li><a target="_blank" href="https://reactjs.org/">React</a></li>
<li><a target="_blank" href="https://angular.io/">Angular</a> </li>
<li><a target="_blank" href="https://vuejs.org/">Vue</a></li>
</ul>
<p>These frameworks and libraries allow you to save time and do more with less code. It is possible to get a job specializing in React, Vue, or Angular. </p>
<p>Here are some suggested learning resources.</p>
<ul>
<li><a target="_blank" href="https://www.youtube.com/watch?v=nTeuhbP7wdE">freeCodeCamp's React YouTube course</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=Fdf5aTYRW0E">Brad Traversy's Angular YouTube course</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=qZXt1Aom3Cs">Brad Traversy's Vue YouTube course</a></li>
</ul>
<h3 id="heading-testing-and-debugging-skills">Testing and Debugging skills</h3>
<p>As you are developing your application, there will be errors in your code that need fixing. Debugging is the act of identifying those errors ("bugs") and fixing them. </p>
<p>Testing is another important skill to learn. Writing tests for your code is a way to ensure that your code is doing what it is supposed to do. </p>
<p>For a more in depth explanation on the different types of testing, I would suggest reading <a target="_blank" href="https://www.freecodecamp.org/news/types-of-software-testing/">this article</a>. </p>
<h3 id="heading-version-control">Version control</h3>
<p>Version control is a way to track and manage changes to the project's code. <a target="_blank" href="https://git-scm.com/">Git</a> is a popular software that is used to track your code. </p>
<p>If you mess up a lot of things in your code, you can use Git to go back to a previous version of your code instead of manually rewriting everything. </p>
<p>Learning Git also allows you to collaborate with others on a team and make changes to the same code base from different locations. </p>
<p>I would suggest starting to <a target="_blank" href="https://www.youtube.com/watch?v=RGOj5yH7evk">learn Git</a> and using a service like <a target="_blank" href="https://github.com/">GitHub</a> to host your personal projects.  </p>
<h3 id="heading-problem-solving">Problem Solving</h3>
<p>The most important skill for any developer is knowing how to problem solve. Companies and clients are looking for you to provide solutions.</p>
<p>It is important to learn how to tackle a problem, break it down into smaller manageable pieces, and troubleshoot the issue in these web applications. </p>
<h2 id="heading-how-can-you-get-a-job-as-a-front-end-developer"><strong>How Can You Get a Job as a Front End Developer?</strong></h2>
<p>Once you have learned the technical aspects of front end development, you have to focus on putting together your job application materials. There are many incredible resources that can help you learn how to get a developer job.</p>
<h3 id="heading-resume-building-resources"><strong>Résumé building resources</strong></h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-get-your-first-dev-job/">How to Get Your First Dev Job – Insights from Reviewing Career Switchers' Résumés</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-write-a-developer-resume-recruiters-will-read/">How to Write a Developer Resume that Recruiters Will Read</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-write-an-awesome-junior-developer-resume-in-a-few-simple-steps-316010db80ec/">How to write an awesome junior developer résumé in a few simple steps</a></li>
</ul>
<h3 id="heading-technical-interview-resources"><strong>Technical interview resources</strong></h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-prepare-for-a-technical-interview/">How to Prepare for a Technical Interview</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-answer-any-technical-interview-question-with-example/">How to Answer Any Technical Interview Question – Example Included</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/what-i-learned-from-doing-60-technical-interviews-in-30-days/">What I Learned from Doing 60+ Technical Interviews in 30 Days</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/is-this-the-best-book-for-coding-interview-preparation/">The Best Book for Technical Coding Interview Prep</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/interviewing-prep-tips-and-tricks/">How to prepare for a technical interview - tips and tricks to help you perform your best</a></li>
</ul>
<h3 id="heading-tips-for-landing-a-job"><strong>Tips for landing a job</strong></h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/networking-for-aspiring-developers/">How to Get Your First Developer Job through Intelligent, Genuine Networking</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=K3B5AltcCTY">Job Hunt Tips in 2021</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=KPzFCZ_u_sY">How to Master Your Job Search</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=SG5Sb5WTV_g">HOW TO USE LINKEDIN AS A DEVELOPER to get a job in tech! How to network!</a></li>
</ul>
<p>Also, here are some resources on how to get started freelancing if you are interested in pursuing that route.</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/what-is-freelancing/">What is Freelancing? How to Find Freelance Jobs Online And Clients in Your City</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/free-web-design-proposal-template/">How to Write Freelance Proposals That Will Win Over Clients + a Free Template</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/freelance-web-developer-guide/">The Complete Freelance Web Developer Guide: How to Make Money Through Freelance Programming Jobs</a></li>
</ul>
<p>I hope you enjoyed this article and best of luck on your path to becoming a front end developer.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Front End Developer vs Back End Developer – Definition and Meaning In Practice ]]>
                </title>
                <description>
                    <![CDATA[ Websites and applications are complex! Buttons and images are just the tip of the iceberg. With this kind of complexity, you need people to manage it, but which parts are the front end developers and back end developers responsible for? [The many la... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/front-end-developer-vs-back-end-developer-definition-and-meaning-in-practice/</link>
                <guid isPermaLink="false">66b8e3260cedc1f2a4f70691</guid>
                
                    <category>
                        <![CDATA[ Back end development  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ backend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Backend Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud Computing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Thu, 18 Jun 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/front-end-back-end.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Websites and applications are complex! Buttons and images are just the tip of the iceberg. With this kind of complexity, you need people to manage it, but which parts are the front end developers and back end developers responsible for?</p>
<ul>
<li>[The many layers of development](#The many layers of development)</li>
<li><a class="post-section-overview" href="#heading-but-were-not-all-full-stack">But we’re not all full stack</a></li>
<li><a class="post-section-overview" href="#heading-so-what-is-the-difference-between-front-end-development-and-back-end-development">So what is the difference between Front End Development and Back End Development?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-front-end-development">What is Front End Development?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-back-end-development">What is Back End Development?</a></li>
<li><a class="post-section-overview" href="#heading-where-things-get-fuzzy">Where things get fuzzy</a></li>
<li><a class="post-section-overview" href="#heading-resources-to-learn">Resources to learn</a></li>
</ul>
<h2 id="heading-the-many-layers-of-development">The many layers of development</h2>
<p>Whether you’re working on a website or a native iOS app, all development environments share a common theme — there’s a front end to an application and a back end.</p>
<p>This line can get blurry, especially given the rise of javascript and the <a target="_blank" href="https://en.wikipedia.org/wiki/Serverless_computing">serverless</a> world. With the tooling somewhat merging together, we might sometimes wonder if we’re a <a target="_blank" href="https://www.colbyfayock.com/2020/02/how-to-become-a-full-stack-web-developer-in-2020/">full stack developer</a>.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/holtbt/status/977419276251430912"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<h2 id="heading-but-were-not-all-full-stack">But we’re not all full stack</h2>
<p>As much as we might all <a target="_blank" href="https://full-stack.netlify.app/">want to be</a>, we’re not all full stack developers. Personally, I find myself able to be productive in the back end of an application, but it’s not my strength and I much prefer to be heads down building UIs.</p>
<p>And some people are the opposite, where they are strongest dealing with building APIs in the back end of an application and while they can build out a UI, it might be more of a prototype-like experience than a fleshed out application.</p>
<h2 id="heading-so-what-is-the-difference-between-front-end-development-and-back-end-development">So what is the difference between Front End Development and Back End Development?</h2>
<p>Even if you are a full stack developer, that doesn’t mean there’s not a division of responsibilities.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/front-end-vs-back-end-engineer-2.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Front End Engineer vs Back End Engineer</em></p>
<p>So what do those look like?</p>
<h2 id="heading-what-is-front-end-development">What is Front End Development?</h2>
<p>The front end of an application typically refers to the layer that represents the UI (user interface). This can include anything from a static site with HTML and CSS to a full <a target="_blank" href="https://reactjs.org/">React</a> app that powers the UI.</p>
<h3 id="heading-what-did-front-end-development-traditionally-look-like">What did Front End Development traditionally look like?</h3>
<p>Javascript currently rules the front end web, but that wasn’t always the case. While it could have been used to add little bits of interaction to a site, typically front ends were rendered using server-side templating languages like framework-driven <a target="_blank" href="https://www.php.net/">PHP</a> and <a target="_blank" href="http://www.template-toolkit.org/">Template Toolkit</a> (<a target="_blank" href="https://www.perl.org/">Perl</a>).</p>
<p>This grew to be super popular in practice with home grown frameworks or tools like <a target="_blank" href="https://wordpress.org/">Wordpress</a> that used PHP to drive a massive community of developers who built their websites with those tools.</p>
<p>The way it worked was the templating language was able to get its data straight from the server as it was rendered. When a browser requested the page directly from the origin (the server itself), whatever data the template would need, the application logic would provide at that time.</p>
<p>Some of the more traditional front end tools include:</p>
<ul>
<li>Libraries like <a target="_blank" href="https://jquery.com/">jQuery</a> or <a target="_blank" href="https://mootools.net/">MooTools</a></li>
<li>Website frameworks like <a target="_blank" href="https://wordpress.com/">Wordpress</a></li>
<li>Plain <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS">CSS</a></li>
<li>Abundant use of <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table">Table</a> elements</li>
</ul>
<p>But as time went on, javascript kept getting more mature as a language and browsers kept getting more powerful, which led to the idea that we could move more of that work to the browser to build faster and more interactive experiences.</p>
<h3 id="heading-what-does-front-end-development-look-like-now">What does Front End Development look like now?</h3>
<p>Now it’s common to see javascript-heavy websites and apps built using UI frameworks like <a target="_blank" href="https://reactjs.org/">React</a>, <a target="_blank" href="https://vuejs.org/">Vue</a>, and <a target="_blank" href="https://angular.io/">Angular</a>. These tools provide abstractions that allow developers to build complex UIs with reusable patterns like components.</p>
<p>When the browser loads the page, the page receives an initial HTML document that also includes the script tag to the javascript (same as always). But once that javascript loads, it reaches out to APIs using browser requests that when completed, update the page to fill in any kind of dynamic data that you’d typically get along with that first HTML document.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/building-website-with-more-steps.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>It's like building a website... with more steps</em></p>
<p>While it sounds like more steps, it commonly provides a faster initial page load and render, not to mention it has a great developer experience. By delivering less on that first request and prioritizing what loads after that, it usually ends up as a better user experience.</p>
<p>Some of the front end tools that are more common and growing in popularity  include:</p>
<ul>
<li>UI frameworks like <a target="_blank" href="https://reactjs.org/">React</a> or <a target="_blank" href="https://vuejs.org/">Vue</a></li>
<li>Web frameworks like <a target="_blank" href="https://www.gatsbyjs.org/">Gatsby</a></li>
<li>Compilers like <a target="_blank" href="https://babeljs.io/">Babel</a></li>
<li>Bundlers like <a target="_blank" href="https://webpack.js.org/">Webpack</a></li>
<li>CSS tools like <a target="_blank" href="https://sass-lang.com/">Sass</a></li>
</ul>
<p>But those APIs, whether ones we pay for or create ourselves, need to be built <em>somewhere</em>. That’s where the back end comes in.</p>
<h2 id="heading-what-is-back-end-development">What is Back End Development?</h2>
<p>The back end layer is usually where the business logic occurs. This can be super complex like the rules that determine revenue for an e-commerce company or something more common like a user profile.</p>
<h3 id="heading-what-did-back-end-development-traditionally-look-like">What did Back End Development traditionally look like?</h3>
<p>The back ends of applications were historically built using server-side languages like <a target="_blank" href="https://www.php.net/">PHP</a> or <a target="_blank" href="https://www.ruby-lang.org/en/">Ruby</a>. The idea is that you have a server that you need to perform complex operations on, so the way to do that is with a language that server would understand.</p>
<p>On each request to the server, the backend would perform the full stack of the operations, including rendering out the front end. By using frameworks or DIY architectures, the back end would accept the request, figure out what it should do with that request, run any business logic needed with the request, and provide the front end any data that it would need to display a response to that request.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/front-end-back-end-500-error.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Back end giving the front end a 500 Internal Server Error</em></p>
<p>Some of the more traditional back end tools include:</p>
<ul>
<li>On-premise or remotely managed servers like <a target="_blank" href="https://www.rackspace.com/">Rackspace</a></li>
<li>HTTP servers using <a target="_blank" href="https://httpd.apache.org/">Apache</a></li>
<li>Databases like <a target="_blank" href="https://www.mysql.com/">MySQL</a></li>
<li>Server side languages like <a target="_blank" href="https://www.php.net/">PHP</a> or <a target="_blank" href="https://www.perl.org/">Perl</a></li>
<li>Application frameworks like <a target="_blank" href="https://rubyonrails.org/">Ruby on Rails</a></li>
</ul>
<h3 id="heading-what-does-back-end-development-look-like-now">What does Back End Development look like now?</h3>
<p>Back end stacks look somewhat similar to the way they did before, aside from newer code patterns, except more often you’ll see the back ends provide data through APIs via HTTP requests instead of directly to the templates the front end team are working on.</p>
<p>While the foundation isn’t super different, it actually be comes increasingly complex as you have to deal with different security implications that could compromise your system if not properly configured such as leaving an API open to the public that returns sensitive user data.</p>
<p>But also how the server operates can be completely different. While previously, we might run our python on our own managed server (we still can), we can now make use of serverless functions with tools like <a target="_blank" href="https://aws.amazon.com/lambda/">AWS Lambda</a> that simplify how we manage code.</p>
<p>While “<a target="_blank" href="https://en.wikipedia.org/wiki/Serverless_computing">serverless</a>” doesn’t necessarily mean there are literally no servers, it means that as a service, the developer doesn’t have to worry about maintaining that server and can instead just focus on the code they need to run.</p>
<p>Some of the back end tools that are more common and growing in popularity include:</p>
<ul>
<li>Cloud servers like <a target="_blank" href="https://aws.amazon.com/ec2/">AWS EC2</a></li>
<li>Serverless services like <a target="_blank" href="https://aws.amazon.com/lambda/">AWS Lambda</a></li>
<li>NoSQL databases like <a target="_blank" href="https://www.mongodb.com/">MongoDB</a></li>
<li>Languages like <a target="_blank" href="https://www.python.org/">Python</a> or javascript via <a target="_blank" href="https://nodejs.org/">NodeJS</a></li>
<li>Web application frameworks like <a target="_blank" href="https://www.serverless.com/">Serverless Framework</a></li>
</ul>
<h2 id="heading-where-things-get-fuzzy">Where things get fuzzy</h2>
<p>Part of the twist with back ends is now you can write your back end with javascript. With the inception of <a target="_blank" href="https://nodejs.org/en/">Node.js</a>, developers were given the ability to use their favorite browser language to do most of the same things they were used to and familiar with but now on a server.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/nodejs-never-stopped-to-think-if-should.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Never stopped to think if we should write JS on a server</em></p>
<p>While not everyone is fond of running javascript as a server side language, it became a little easier to use the same language to write the full stack of an application. This changed the game a bit as far as front ends and back ends were concerned.</p>
<p>But it’s also started to come full circle where you now see systems that build APIs right <a target="_blank" href="https://redwoodjs.com/tutorial/redwood-file-structure">next to the front end</a> similar to what you might see in a traditional stack.</p>
<h2 id="heading-front-end-vs-back-end">Front End vs Back End</h2>
<p>Regardless of the stack, there will always be the separation of concerns. The UI and all of the interaction, whether rendered on the server or in the browser, is what makes the front end the front end and the data and business logic, whether coming from the server in your company’s closet or a managed function, is what makes the back end the back end.</p>
<p>Whether you prefer to work on the user facing features or build the logic that lets them do things, there are plenty of resources to get started.</p>
<h2 id="heading-resources-to-learn">Resources to learn</h2>
<h3 id="heading-front-end">Front End</h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/">freecodecamp.org Responsive Web Design Certification</a> (freecodecamp.org)</li>
<li><a target="_blank" href="https://beginnerjavascript.com/">Beginner Javascript</a> (beginnerjavascript.com - Wes Bos)</li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=Ke90Tje7VS0">React Tutorial for Beginners</a> (youtube.com - Programming with Mosh)</li>
<li><a target="_blank" href="https://frontendmasters.com/">Front End Masters</a> (frontendmasters.com)</li>
</ul>
<h3 id="heading-back-end">Back End</h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/learn">freecodecamp.org APIs and Microservices Certification</a> (freecodecamp.org)</li>
<li><a target="_blank" href="https://kentcdodds.com/blog/super-simple-start-to-serverless/">Super simple start to serverless</a> (kentcdodds.com)</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/aws-certified-cloud-practitioner-training-2019-free-video-course/">AWS Certified Cloud Practitioner Training 2019 - A Free 4-hour Video Course</a> (freecodecamp.org)</li>
<li><a target="_blank" href="https://www.edx.org/course/cs50s-introduction-to-computer-science">CS50's Introduction to Computer Science</a> (edx.org)</li>
</ul>
<h3 id="heading-all-the-above">All the above</h3>
<ul>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/02/how-to-become-a-full-stack-web-developer-in-2020/">How to Become a Full Stack Web Developer in 2020</a> (colbyfayock.com)</li>
<li><a target="_blank" href="https://egghead.io/?af=atzgap">Egghead.io</a> (egghead.io)</li>
<li><a target="_blank" href="https://www.100daysofcode.com/">100 Days of Code</a> (100daysofcode.com)</li>
<li><a target="_blank" href="https://www.udemy.com/course/the-web-developer-bootcamp/">The Web Developer Bootcamp</a> (udemy.com - Colt Steele)</li>
</ul>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add Search to a React App with Fuse.js ]]>
                </title>
                <description>
                    <![CDATA[ Search is a powerful way help people visiting your site find the content that's most important to them. But often it's really challenging to figure out the rules and logic to make that happen. In this article, we'll see how can we can use fuse.js to ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-search-to-a-react-app-with-fuse-js/</link>
                <guid isPermaLink="false">66b8e33e6a98b2a27ee1f348</guid>
                
                    <category>
                        <![CDATA[ fuse.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ json ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 26 May 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/fusejs-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Search is a powerful way help people visiting your site find the content that's most important to them. But often it's really challenging to figure out the rules and logic to make that happen. In this article, we'll see how can we can use fuse.js to add search to our apps.</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-fusejs">What is fuse.js?</a></li>
<li><a class="post-section-overview" href="#heading-why-is-search-important">Why is search important?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-step-0-bootstrapping-our-app">Step 0: Bootstrapping our app</a></li>
<li><a class="post-section-overview" href="#heading-step-1-installing-fusejs">Step 1: Installing Fuse.js</a></li>
<li><a class="post-section-overview" href="#heading-step-2-creating-a-new-fuse-search-instance">Step 2: Creating a new Fuse search instance</a></li>
<li><a class="post-section-overview" href="#heading-step-3-setting-up-dynamic-search-based-on-user-input">Step 3: Setting up dynamic search based on user input</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/GZl-yEz4_qw" 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-is-fusejs">What is fuse.js?</h2>
<p><a target="_blank" href="https://fusejs.io/">Fuse.js</a> is a JavaScript library that provides fuzzy search capabilities for applications and websites. It's nice and easy to use out of the box, but also includes configuration options that allow you to tweak and create powerful solutions.</p>
<h2 id="heading-why-is-search-important">Why is search important?</h2>
<p>Whether you're a content creator or are trying to sell a product with your website, it's important to help your visitors actually find what they're looking for. </p>
<p>If you're building an ecommerce website, you want someone to be able to easily find your Bender vinyl figures rather than having to dig through the entire catalog first.</p>
<h2 id="heading-what-are-we-going-to-build">What are we going to build?</h2>
<p>We're going to start off with a basic Create React App example. It's going to include some character info as structured data for one of my favorite shows Futurama that's simply dumped out into an HTML list.</p>
<p>With that list, we're going to use fuse.js to provide client-side search capabilities, allowing us to demonstrate searching for the character we're looking for by their name and other details.</p>
<h2 id="heading-step-0-bootstrapping-our-app">Step 0: Bootstrapping our app</h2>
<p>To get started, we're going to need content to work with. I got started by building a list of characters from Futurama as structured json data that I put in a list with a fresh Create React App.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-demo.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Futurama character search demo</em></p>
<p>You'll also notice I've already added an input for our search. It's not yet functional but we'll use that to get started.</p>
<p>If you'd like to start off at the same place, I created a branch with my demo repo that you can clone locally to walk through the project with me!</p>
<pre><code class="lang-shell">git clone --single-branch --branch start git@github.com:colbyfayock/my-futurama-characters.git
</code></pre>
<p><a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/tree/start">Git branch "start"</a></p>
<p>Or <a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/commit/20d4e42aaf69e214b63e684e012cd2f8c95d427b">follow along with the commit</a>.</p>
<h2 id="heading-step-1-installing-fusejs">Step 1: Installing Fuse.js</h2>
<p>First thing we'll want to do is actually add Fuse.js to our app. In your project, run:</p>
<pre><code class="lang-shell">yarn add fuse.js
# or
npm install --save fuse.js
</code></pre>
<p>This will save the dependency to our project so that we'll be able to use it in our project.</p>
<p>Next we'll want to import the dependency to our app so that we can start building with it. At the top of your file, in our case <code>src/App.js</code> if you're following along with me in a new Create React App project, add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> Fuse <span class="hljs-keyword">from</span> <span class="hljs-string">'fuse.js'</span>;
</code></pre>
<p>If you want to test that it's working, you can <code>console.log(Fuse)</code> and see our <code>Fuse</code> class we'll use to create our search capabilities.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/fusejs-class.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Imported fuse.js class</em></p>
<p>And with that, we're ready to get started!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/commit/54720daffa6ff415997c319b12f8f44d7ec8b748">Follow along with the commit</a></p>
<h2 id="heading-step-2-creating-a-new-fuse-search-instance">Step 2: Creating a new Fuse search instance</h2>
<p>To use Fuse.js, we'll want to first create a new instance of it.</p>
<p>At the top of your component, add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fuse = <span class="hljs-keyword">new</span> Fuse(characters, {
  <span class="hljs-attr">keys</span>: [
    <span class="hljs-string">'name'</span>,
    <span class="hljs-string">'company'</span>,
    <span class="hljs-string">'species'</span>
  ]
});
</code></pre>
<p>With this does:</p>
<ul>
<li>Creates a new instance of Fuse</li>
<li>Passes in our <code>characters</code> array of objects</li>
<li>Specifies the 3 keys in our data that we want to search on</li>
</ul>
<p>Next, to perform the search, we can add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> results = fuse.search(<span class="hljs-string">'bender'</span>);
</code></pre>
<p>And if we console log out the results, we can see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/basic-fusejs-search-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Basic fuse.js search results</em></p>
<p>You'll notice that we have more results than our friend Bender though. Fuse.js provides a "fuzzy search" meaning it tries to help you in case you're not sure what you're looking for or if you're misspelling your query.</p>
<p>To get an idea of how this works, let's add the <code>includeScore</code> option to our search:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fuse = <span class="hljs-keyword">new</span> Fuse(characters, {
  <span class="hljs-attr">keys</span>: [
    <span class="hljs-string">'name'</span>,
    <span class="hljs-string">'company'</span>,
    <span class="hljs-string">'species'</span>
  ],
  <span class="hljs-attr">includeScore</span>: <span class="hljs-literal">true</span>
});
</code></pre>
<p>Now we can see the <code>score</code> attribute in our results object.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/fusejs-search-results-with-score.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Fuse.js search results with score</em></p>
<p>You'll notice that our first result has a really low score. With fuse.js, a lower score means it's closer to an exact match.</p>
<p>A score of 0 indicates a perfect match, while a score of 1 indicates a complete mismatch.</p>
<p>It's saying that is incredibly likely that the first result is what we're looking for, but it's not confident in the others.</p>
<p>So with our results, we want to actually connect that to our UI. If you notice our array output is different than what we are mapping through for the HTML list, so let's create a new variable that we can change it to:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> results = fuse.search(<span class="hljs-string">'bender'</span>);
<span class="hljs-keyword">const</span> characterResults = results.map(<span class="hljs-function"><span class="hljs-params">character</span> =&gt;</span> character.item);
</code></pre>
<p>What this is doing is creating a new array using the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a> method that will only include the <code>item</code> property from each array object.</p>
<p>Then if we replace our <code>characters</code> map inside of our list with <code>characterResults.map</code>:</p>
<pre><code class="lang-jsx">&lt;ul className=<span class="hljs-string">"characters"</span>&gt;
  {characterResults.map(<span class="hljs-function"><span class="hljs-params">character</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> { name, company, species, thumb } = character;
</code></pre>
<p>We can now see that our page only shows the results for "bender"!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-filtered-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with filtered results</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/commit/adbf30a872fa134cfca4e142ba479877b9665e9a">Follow along with the commit!</a></p>
<h2 id="heading-step-3-setting-up-dynamic-search-based-on-user-input">Step 3: Setting up dynamic search based on user input</h2>
<p>Now that we have a hard-coded search working, we want someone to actually be able to use the search input to search!</p>
<p>To achieve this, we're going to use the <code>useState</code> hook and listen for changes to the <code>input</code> field, which will dynamically create a search for our data.</p>
<p>First, import the <code>useState</code> hook from React:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
</code></pre>
<p>Next, let's use that hook to create a state instance:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [query, updateQuery] = useState(<span class="hljs-string">''</span>);
</code></pre>
<p>Here, we're creating a new state of <code>query</code> that we can update with <code>updateQuery</code> that defaults to an empty string (<code>''</code>).</p>
<p>With that, let's tell our search input to use that <code>query</code> value as it's value:</p>
<pre><code class="lang-jsx">&lt;input type=<span class="hljs-string">"text"</span> value={query} /&gt;
</code></pre>
<p>At this point, nothing should be different, as we are using a blank query.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-filtered-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with filtered results - nothing changed</em></p>
<p>Now let's add an event handler to our input that we can use to update our state:</p>
<pre><code class="lang-jsx">&lt;input type=<span class="hljs-string">"text"</span> value={query} onChange={onSearch} /&gt;
</code></pre>
<p>And we'll want to create that function so we can use it:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onSearch</span>(<span class="hljs-params">{ currentTarget }</span>) </span>{
  updateQuery(currentTarget.value);
}
</code></pre>
<p>This will update our <code>query</code> with the input's value any time it changes.</p>
<p>Now that our <code>query</code>  will have what we want to search for, we can update our search instance:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> results = fuse.search(query);
</code></pre>
<p>And now if you reload the page, it's blank! ?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-no-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with no results</em></p>
<p>That's because by default, Fuse sees our empty query and doesn't match it to anything. If we now search for something like <code>slurms</code>, we can see our search dynamically update with results!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with results for "slurms"</em></p>
<p>If we wanted to fix this though so that all of our results show when there's no query, we can do so with an <code>if</code> statement or in my example, a ternary, that will show all of the characters if there is no query:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> characterResults = query ? results.map(<span class="hljs-function"><span class="hljs-params">character</span> =&gt;</span> character.item) : characters;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-demo.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with all results</em></p>
<p>And with that, we have our basic search!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-results-query.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with filtered results for "zoidberg"</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/commit/1b8918fc56f31517686a6c73f1969787728736ac">Follow along with the commit!</a></p>
<h2 id="heading-what-can-i-do-next">What can I do next?</h2>
<h3 id="heading-tuning-your-search">Tuning your search</h3>
<p>Fuse.js comes with a lot of options that you can use to tune your search to however you'd like. Want to only show confident results? Use the <code>threshold</code> option! Want case sensitive queries? Use the <code>isCaseSensitive</code> option!</p>
<p><a target="_blank" href="https://fusejs.io/api/options.html">https://fusejs.io/api/options.html</a></p>
<h3 id="heading-setting-the-default-query-with-url-parameters">Setting the default query with URL parameters</h3>
<p>Sometimes you want someone to be able to link to a particular set of results. To do this, we might want to be able to add a new URL parameter like <code>?q=bender</code>.</p>
<p>To make this work, you can grab that URL parameter with javascript and use that value to set our <code>query</code> state.</p>
<h2 id="heading-join-the-conversation">Join the conversation!</h2>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/colbyfayock/status/1265298322891378688"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Tailwind CSS and How Can I Add it to my Website or React App? ]]>
                </title>
                <description>
                    <![CDATA[ CSS is a technology that can be your best or worst friend. While it's incredibly flexible and can produce what seems like magic, without the proper care and attention, it can become hard to manage like any other code.  How can Tailwind CSS help us to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-tailwind-css-and-how-can-i-add-it-to-my-website-or-react-app/</link>
                <guid isPermaLink="false">66b8e39e0196ee8e3efce546</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS Framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PostCSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tailwind ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 19 May 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/tailwind-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>CSS is a technology that can be your best or worst friend. While it's incredibly flexible and can produce what seems like magic, without the proper care and attention, it can become hard to manage like any other code. </p>
<p>How can Tailwind CSS help us to take control of our styles?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-tailwind">What is Tailwind?</a></li>
<li><a class="post-section-overview" href="#heading-so-what-makes-tailwind-great">So what makes Tailwind great?</a></li>
<li><a class="post-section-overview" href="#heading-part-1-adding-tailwind-css-to-a-static-html-page">Part 1: Adding Tailwind CSS to a static HTML page</a></li>
<li><a class="post-section-overview" href="#heading-part-2-adding-tailwind-css-to-a-react-app">Part 2: Adding Tailwind CSS to a React app</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/7KeZcRMltP0" 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-is-tailwind">What is Tailwind?</h2>
<p><a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a> is a "utility-first" CSS framework that provides a deep catalog of CSS classes and tools that lets you easily get started styling your website or application.</p>
<p>The underlying goal is that as you're building your project, you don't need to deal with cascading styles and worrying about how to override that 10-selector pileup that's been haunting your app for the last 2 years.</p>
<h2 id="heading-so-what-makes-tailwind-great">So what makes Tailwind great?</h2>
<p>Taildwind's solution is to provide a wide variety of CSS classes that each have their own focused use. Instead of a class called <code>.btn</code> that is created with a bunch of CSS attributes directly, in Tailwind, you would either apply a bunch of classes like <code>bg-blue-500 py-2 px-4 rounded</code> to the button element or build a <code>.btn</code> class by <a target="_blank" href="https://tailwindcss.com/docs/functions-and-directives/#apply">applying</a> those utility class to that selector.</p>
<p>While Tailwind has a lot more going for it, we're going to focus on these basics for this tutorial, so let's dig in!</p>
<h2 id="heading-part-1-adding-tailwind-css-to-a-static-html-page">Part 1: Adding Tailwind CSS to a static HTML page</h2>
<p>We're going to start off by applying Tailwind CSS straight to a static HTML page. The hope is that by focusing on Tailwind and not the app, we can get a better understanding of what's actually happening with the framework.</p>
<h3 id="heading-step-1-creating-a-new-page">Step 1: Creating a new page</h3>
<p>You can get started by simply creating a new HTML file. For the content, you can use whatever you want, but I'm going to use <a target="_blank" href="http://fillerama.io/">fillerama.io</a> so the filler content is a bit more fun.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-with-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New HTML page with content</em></p>
<p>If you want to simplify this step, you can just <a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/c7db11899c9cd193cdd666fd228cfaefe75623f2#diff-eacf331f0ffc35d4b482f1d15a887d3b">copy the file I created</a> to get started.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/c7db11899c9cd193cdd666fd228cfaefe75623f2">Follow along with the commit!</a></p>
<h3 id="heading-step-2-adding-tailwind-css-via-cdn">Step 2: Adding Tailwind CSS via CDN</h3>
<p>Tailwind typically recommends that you install through <a target="_blank" href="https://www.npmjs.com/package/tailwindcss">npm</a> to get the full functionality, but again, we're just trying to understand how this works first.</p>
<p>So let's add a link to the CDN file in the <code>&lt;head&gt;</code> of our document:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
</code></pre>
<p>Once you save and reload the page, the first thing you'll notice is that all of the styles were stripped!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-tailwind-base.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with the Tailwind CSS base</em></p>
<p>This is expected. Tailwind includes a set of <a target="_blank" href="https://tailwindcss.com/docs/preflight">preflight styles</a> to fix cross-browser inconsistencies. For one, they include the popular <a target="_blank" href="https://github.com/necolas/normalize.css/">normalize.css</a> which they build upon with their own styles.</p>
<p>But we're going to learn how to use Tailwind to add back our styles and set things up how we want!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/b431b75cee0a03154a70b194b6dfcf028bc65942">Follow along with the commit!</a></p>
<h3 id="heading-step-3-using-tailwind-css-to-add-styles-to-your-page">Step 3: Using Tailwind CSS to add styles to your page</h3>
<p>Now that we have Tailwind installed, we've added the ability to make use of their huge library of utility classes that we'll now use to add styles back to our page.</p>
<p>Let's start off by adding some margin to all of our paragraphs (<code>&lt;p&gt;</code>) and our list elements (<code>&lt;ol&gt;</code>, <code>&lt;ul&gt;</code>). We can do this by adding the <code>.my-5</code> class to each element like so:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"my-5"</span>&gt;</span>
  Bender, quit destroying the universe! Yeah, I do that with my stupidness. I never loved you. Moving along…
  Belligerent and numerous.
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>The class name follows a pattern that you'll notice with the rest of the utility classes – <code>.my-5</code> stands for margin (m) applied to the y-axis (y) with a value of 5 which in Tailwind's case, it uses <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units">rem</a>, so the value is 5rem.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-paragraph-styles.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with basic paragraph styles</em></p>
<p>Next, let's make our headers look like actual headers. Starting with our <code>h1</code> tag, let's add:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-2xl font-bold mt-8 mb-5"</span>&gt;</span>
</code></pre>
<p>Here's what's happening:</p>
<ul>
<li><code>text-2xl</code>: set the text size (font-size) to 2xl. In Tailwind, that 2xl will equate to 1.5rem</li>
<li><code>font-bold</code>: set the weight of the text (font-weight) to bold</li>
<li><code>mt-8</code>: Similar to <code>my-5</code>, this will set the margin top (t) to 8rem</li>
<li><code>mb-5</code>: And this will set the margin bottom (b) to 5rem</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-header-styles.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with styled H1</em></p>
<p>With those classes added to the <code>h1</code>, let's apply those same exact classes to the rest of our header elements, but as we go down the list, reduce the size of the font size, so it will look like:</p>
<ul>
<li>h2: <code>text-xl</code></li>
<li>h3: <code>text-lg</code></li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-all-headers-style.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with all headers styled</em></p>
<p>Now let's make our list elements look like lists. Starting with our unordered list (<code>&lt;ul&gt;</code>), let's add these classes:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"list-disc list-inside my-5 pl-2"</span>&gt;</span>
</code></pre>
<p>Here's what we're adding:</p>
<ul>
<li><code>list-disc</code>: set the list-style-stype to disc (the markers on each line item)</li>
<li><code>list-inside</code>: sets the position of the list markers using  relative to the list items and the list itself with list-style-position to inside</li>
<li><code>my-5</code>: set the margin of the y axis to 5rem</li>
<li><code>pl-2</code>: set the left padding to 2rem</li>
</ul>
<p>Then we can apply the exact same classes to our ordered list (<code>&lt;ol&gt;</code>), except instead of <code>list-disc</code>, we want to change our style type to <code>list-decimal</code>, so that we can see numbers given it's an ordered list.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ol</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"list-decimal list-inside my-5 pl-2"</span>&gt;</span>
</code></pre>
<p>And we have our lists!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-styled-lists.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with styled lists</em></p>
<p>Finally, let's make our content a little easier to read by setting a max width and centering the content. On the <code>&lt;body&gt;</code> tag, add the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"max-w-4xl mx-auto"</span>&gt;</span>
</code></pre>
<p>/Note: Typically you wouldn't want to apply these classes to the <code>&lt;body&gt;</code> itself, rather, you can wrap all of your content with a <code>&lt;main&gt;</code> tag, but since we're just trying to get an idea of how this works, we'll roll with this. Feel free to add the <code>&lt;main&gt;</code> tag with those classes instead if you prefer!/</p>
<p>And with that, we have our page!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-content-centered.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with centered content</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/06fd719c98d17e2242b61ec2ab7034436c1c2ba6">Follow along with the commit!</a></p>
<h3 id="heading-step-4-adding-a-button-and-other-components">Step 4: Adding a button and other components</h3>
<p>For the last part of our static example, let's add a button.</p>
<p>The trick with Tailwind, is they intentionally don't provide pre-baked component classes with the idea being that likely people would need to override these components anyways to make them look how they wanted.</p>
<p>So that means, we're going to have to create our own using the utility classes!</p>
<p>First, let's add a new button. Somewhere on the page, add the following snippet. I'm going to add it right below the first paragraph (<code>&lt;p&gt;</code>) tag:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Party with Slurm!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-unstyled-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with unstyled button</em></p>
<p>You'll notice just like all of the other elements, that it's unstyled, however, if you try clicking it, you'll notice it still has the click actions. So let's make it look like a button.</p>
<p>Let's add the following classes:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-white font-bold bg-purple-700 hover:bg-purple-800 py-2 px-4 rounded"</span>&gt;</span>
  Party with Slurm!
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>Here's a breakdown of what's happening:</p>
<ul>
<li><code>text-white</code>: we're setting our text color to white</li>
<li><code>font-bold</code>: set the weight of the text to bold (font-weight)</li>
<li><code>bg-purple-700</code>: set the background color of the button to purple with a shade of 700. The 700 is relative to the other colors defined as purple, you can find these values on their <a target="_blank" href="https://tailwindcss.com/docs/customizing-colors#default-color-palette">palette documentation page</a></li>
<li><code>hover:bg-purple-800</code>: when someone hovers over the button, set the background color to purple shade 800. Tailwind provides these helper classes that allow us to easily define interactive stiles with things like <a target="_blank" href="https://tailwindcss.com/course/hover-focus-and-active-styles/">hover, focus, and active modifiers</a></li>
<li><code>py-2</code>: set the padding of the y-axis to 2rem</li>
<li><code>px-4</code>: set the padding of the  x-axis to 4rem</li>
<li><code>rounded</code>: round the corners of the element by setting the border radius. With tailwind, it sets the border-radius value to .25rem</li>
</ul>
<p>And with all of that, we have our button!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-styled-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with a styled button</em></p>
<p>You can apply this methodology to any other component that you'd like to build. Though it's a manual process, we'll find out how we can make this process easier when building in more dynamic projects like those based on React.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/09312336dce316a75e8007d6c935133490f16c25">Follow along with the commit!</a></p>
<h2 id="heading-part-2-adding-tailwind-css-to-a-react-app">Part 2: Adding Tailwind CSS to a React app</h2>
<p>For more of a real-world use case, we're going to add Tailwind CSS to an app created with <a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">Create React App</a>.</p>
<p>First, we'll walk through the steps you need to take to add tailwind to your project using a fresh install of Create React App, then we'll use our content from our last example to recreate it in React.</p>
<h3 id="heading-step-1-spinning-up-a-new-react-app">Step 1: Spinning up a new React app</h3>
<p>I'm not going to detail this step out too much. The gist is we'll bootstrap a new React app using Create React App.</p>
<p>To get started, you can follow along <a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">with the directions</a> from the official React documentation:</p>
<p><a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">https://reactjs.org/docs/create-a-new-react-app.html</a></p>
<p>And once you start your development server, you should now see an app!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/create-react-app-starting-page.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Create React App starting page</em></p>
<p>Finally, let's migrate all of our old content to our app. To do this, copy everything inside of the <code>&lt;body&gt;</code> tag of our static example and paste it inside of the wrapper <code>&lt;div className="App"&gt;</code> in the new React project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/code-migrating-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Migrating code to React app</em></p>
<p>Next, change all <code>class="</code> attributes from the content we pasted in to <code>className="</code> so that it's using proper React attributes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/code-fixing-class-attribute.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Fixing class attribute in content</em></p>
<p>And lastly, replace the className <code>App</code> on our wrapper <code>&lt;div&gt;</code> to the classes we used on our static <code>&lt;body&gt;</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/code-wrapper-styles.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Adding wrapper styles to the app</em></p>
<p>Once you save your changes and spin back up your server, it will look deceivingly okay.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/react-app-basic-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>React app with basic content</em></p>
<p>React includes some basic styles itself, so while it looks okay, we're not actually using Tailwind yet. So let's get started by installing it!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-dynamic/commit/57993883c77739f71072bcc02ed2398543efc2fd">Follow along with the commit!</a></p>
<h3 id="heading-step-2-installing-tailwind-in-your-react-app">Step 2: Installing Tailwind in your React app</h3>
<p>There are a few steps we'll need to go through in order to get Tailwind up and running on our app. Make sure you follow these steps carefully to ensure it's properly configured.</p>
<p>First, let's add our dependencies:</p>
<pre><code>yarn add tailwindcss postcss-cli autoprefixer
# or
npm install tailwindcss postcss-cli autoprefixer
</code></pre><p><a target="_blank" href="https://tailwindcss.com/docs/installation#4-process-your-css-with-tailwind">Per Tailwind's documentation</a>, we need to be able to process our styles so that they can be properly added to our pipeline. So in the above, we're adding:</p>
<ul>
<li><a target="_blank" href="https://tailwindcss.com/">tailwindcss</a>: the core Tailwind package</li>
<li><a target="_blank" href="https://github.com/postcss/postcss">postcss-cli</a>: Create React App already uses postcss, but we need to configure Tailwind to be part of that build process and run it's own processing</li>
<li><a target="_blank" href="https://github.com/postcss/autoprefixer">autoprefixer</a>: Tailwind doesn't include vendor prefixes, so we want to add autoprefixer to handle this for us. This runs as part of our postcss configuration</li>
</ul>
<p>We're also going to add two dev dependencies that make it easier to work with our code:</p>
<pre><code>yarn add concurrently chokidar-cli -D
# or
npm install concurrently chokidar-cli --save-dev
</code></pre><ul>
<li><a target="_blank" href="https://github.com/kimmobrunfeldt/concurrently">concurrently</a>: a package that lets us set up the ability to run multiple commands at once. This is helpful since we'll need to watch both the styles and React app itself.</li>
<li><a target="_blank" href="https://github.com/kimmobrunfeldt/chokidar-cli">chokidar-cli</a>: let's us watch files and run a command when changed. We'll use this to watch our CSS file and run the build process of the CSS on cahnge</li>
</ul>
<p>Next, let's configure postcss, so create a new file in the root of your project called <code>postcss.config.js</code> and include the following:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Inside postcss.config.js</span>
<span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">plugins</span>: [
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'tailwindcss'</span>),
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'autoprefixer'</span>)
    ],
};
</code></pre>
<p>This will add the Tailwindcss and Autoprefixer plugins to our postcss config.</p>
<p>With our configuration, we need to include it as part of the build and watch processes. Inside <code>package.json</code>, add the following to definitions to your <code>scripts</code> property:</p>
<pre><code class="lang-json"><span class="hljs-string">"build:css"</span>: <span class="hljs-string">"tailwind build src/App.css -o src/index.css"</span>,
<span class="hljs-string">"watch:css"</span>: <span class="hljs-string">"chokidar 'src/App.css' -c 'npm run build:css'"</span>,
</code></pre>
<p>Additionally, modify the <code>start</code> and <code>build</code> scripts to now include those commands:</p>
<pre><code class="lang-json"><span class="hljs-string">"start"</span>: <span class="hljs-string">"concurrently -n Tailwind,React 'npm run watch:css' 'react-scripts start'"</span>,
<span class="hljs-string">"build"</span>: <span class="hljs-string">"npm run build:css &amp;&amp; react-scripts build"</span>,
</code></pre>
<p>With our configuration ready to go, let's try our styles back to where they were when we left off from the static example.</p>
<p>Inside the <code>App.css</code> file, replace the entire content with:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@tailwind</span> base;
<span class="hljs-keyword">@tailwind</span> components;
<span class="hljs-keyword">@tailwind</span> utilities;
</code></pre>
<p>This is going to import Tailwind's base styles, components, and utility classes that allow Tailwind to work as you would expect it to.</p>
<p>We can also remove the <code>App.css</code> import from our <code>App.js</code> file because it's now getting injected directly into our <code>index.css</code> file. So remove this line:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
</code></pre>
<p>Once you're done, you can start back up your development server! If it was already started, make sure to restart it so all of the configuration changes take effect.</p>
<p>And now the page should look exactly like it did in our static example!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/react-app-with-styled-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>React app with content styled</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-dynamic/commit/5f50cc218ef58f469dad7f09bdad31f36b58a896">Follow along with the commit!</a></p>
<h3 id="heading-step-3-creating-a-new-button-component-class-with-tailwind">Step 3: Creating a new button component class with Tailwind</h3>
<p>Tailwind doesn't ship with prebaked component classes, but it does make it easy to create them!</p>
<p>We're going to use our button that we already created as an example of creating a new component. We'll create a new class <code>btn</code> as well as a color modifier <code>btn-purple</code> to accomplish this.</p>
<p>The first thing we'll want to do is open up our App.css file where we'll create our new class. Inside that file, let's add:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.btn</span> {
  @apply font-bold py-2 px-4 rounded;
}
</code></pre>
<p>If you remember from our HTML, we're already including those same classes to our <code>&lt;button&gt;</code> element.  Tailwind let's us "apply" or include the styles that make up these utility classes to another class, in this case, the <code>.btn</code> class.</p>
<p>And now that we're creating that class, let's apply it to our button:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn text-white bg-purple-700 hover:bg-purple-800"</span>&gt;</span>
  Party with Slurm!
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>And if we open up our page, we can see our button still looks the same. If we inspect the element, we can see our new <code>.btn</code> class generated with those styles.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/react-tailwind-button-class.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>.btn class in a React app with Tailwind</em></p>
<p>Next, let's create a color modifier. Similar to what we just did, we're going to add the following rules:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.btn-purple</span> {
  @apply bg-purple-700 text-white;
}

<span class="hljs-selector-class">.btn-purple</span><span class="hljs-selector-pseudo">:hover</span> {
  @apply bg-purple-800;
}
</code></pre>
<p>Here, we're adding our background color and our text color to our button class. We're also applying a darker button color when someone hovers over the button.</p>
<p>We'll also want to update our HTML button to include our new class and remove the ones we just applied:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn btn-purple"</span>&gt;</span>
  Party with Slurm!
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>And with that change, we can still see that nothing has changed and we have our new button class!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/react-tailwind-styled-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Styled button in React with Tailwind</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-dynamic/commit/7a76e8a4583b0a4c523ea902d73e889c7b86f437">Follow along with the commit!</a></p>
<h2 id="heading-applying-these-concepts-to-more-components">Applying these concepts to more components</h2>
<p>Through this walkthrough, we learned how to create a new component class using the Tailwind apply directive. This allowed us to create reusable classes that represent a component like a button.</p>
<p>We can apply this to any number of components in our design system. For instance, if we wanted to always show our lists the way we set them up here, we could create a <code>.list-ul</code> class that represented an unordered list with the Tailwind utilities <code>list-disc list-inside my-5 pl-2</code> applied.</p>
<h2 id="heading-what-tips-and-tricks-do-you-like-to-use-with-tailwind">What tips and tricks do you like to use with Tailwind?</h2>
<p>Share with me on <a target="_blank" href="https://twitter.com/colbyfayock">Twitter</a>!</p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Pure CSS to Create a Beautiful Loading Animation for your App ]]>
                </title>
                <description>
                    <![CDATA[ If you've been around the internet lately, you've most likely seen a nice subtle loading animation that fills page content before gracefully loading in.  Some of the social giants like Facebook even use this approach to give page loading a better exp... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-css-to-create-a-beautiful-loading-animation-for-your-app/</link>
                <guid isPermaLink="false">66b8e3730cedc1f2a4f7069f</guid>
                
                    <category>
                        <![CDATA[ animation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ animations ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML5 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Inspiration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Pure CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Applications ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 05 May 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/loading-animation.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you've been around the internet lately, you've most likely seen a nice subtle loading animation that fills page content before gracefully loading in. </p>
<p>Some of the social giants like Facebook even use this approach to give page loading a better experience. How can we do that with just some simple CSS?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-just-want-the-snippet">Just want the snippet?</a></li>
<li><a class="post-section-overview" href="#heading-part-1-creating-our-loading-animation">Part 1: Creating our loading animation</a></li>
<li><a class="post-section-overview" href="#heading-part-2-using-our-loading-animation-in-a-dynamic-app">Part 2: Using our loading animation in a dynamic app</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/auyZWWjXJCo" 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-are-we-going-to-build">What are we going to build?</h2>
<p>We're going to create a loading animation using a CSS class that you can apply to pretty much any element you want (within reason).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/loading-animation.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Loading animation preview</em></p>
<p>This gives you great flexibility to use it and makes the solution nice and simple with only CSS.</p>
<p>While the snippet is pretty small and you could just copy and paste it, I'll walk you through what's happening and an example of using it dynamically when loading data.</p>
<h2 id="heading-just-want-the-snippet">Just want the snippet?</h2>
<p>You can grab it here!</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="d155418975d1e0e04b2805e285296033">
        <script src="https://gist.github.com/colbyfayock/d155418975d1e0e04b2805e285296033.js"></script></div><h2 id="heading-do-i-need-to-know-how-to-animate-before-this-tutorial">Do I need to know how to animate before this tutorial?</h2>
<p>No! We'll walk through in detail exactly what you need to do. In fact, the animation in this tutorial is relatively simple, so let's dig in!</p>
<h2 id="heading-part-1-creating-our-loading-animation">Part 1: Creating our loading animation</h2>
<p>This first part is going to focus on getting the loading animation together and seeing it on a static HTML website. The goal is to walk through actually creating the snippet. We'll only use HTML and CSS for this part.</p>
<h3 id="heading-step-1-creating-some-sample-content">Step 1: Creating some sample content</h3>
<p>To get started, we'll want a little sample content. There's really no restrictions here, you can create this with basic HTML and CSS or you can add this to your Create React App!</p>
<p>For the walk through, I'm going to use HTML and CSS with a few examples of content that will allow us to see this in effect.</p>
<p>To get started, create a new HTML file. Inside that HTML file, fill it with some content that will give us the ability to play with our animation. I'm going to use <a target="_blank" href="http://fillerama.io/">fillerama</a> which uses lines from my favorite TV show <a target="_blank" href="https://en.wikipedia.org/wiki/Futurama">Futurama</a>!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/static-html-css-website-fillerama.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Static HTML &amp; CSS webpage with content from fillerama.io</em></p>
<p>If you're going to follow along with me, here's what my project looks like:</p>
<pre><code>my-css-loading-animation-<span class="hljs-keyword">static</span>
- index.html
- main.css
</code></pre><p><a target="_blank" href="https://github.com/colbyfayock/my-css-loading-animation-static/commit/9aa7925f7048fa1b73fef74d0d56380c29fc5d73">Follow along with the commit!</a></p>
<h3 id="heading-step-2-starting-with-a-foundation-loading-class">Step 2: Starting with a foundation loading class</h3>
<p>For our foundation, let's create a new CSS class. Inside our CSS file, let's add:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.loading</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#eceff1</span>;
}
</code></pre>
<p>With that class, let's add it to a few or all of our elements. I added it to a few paragraphs, headings, and lists.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"loading"</span>&gt;</span>For example...
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/static-html-css-gray-background.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Static HTML &amp; CSS webpage with a gray background for the content</em></p>
<p>That gives us a basic background, but we'd probably want to hide that text. When it's loading, we won't have that text yet, so most likely we would want to use filler text or a fixed height. Either way, we can set the color to transparent:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.loading</span> {
  <span class="hljs-attribute">color</span>: transparent;
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#eceff1</span>;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/static-html-css-gray-background-hidden-text.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Static HTML &amp; CSS webpage with a gray background and transparent color for the content</em></p>
<p>If you notice with list elements, whether you apply the class to the top level list element (<code>&lt;ol&gt;</code> or <code>&lt;ul&gt;</code>) vs the list item itself (<code>&lt;li&gt;</code>), it looks like one big block. If we add a little margin to the bottom of all list elements, we can see a different in how they display:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">li</span> {
  <span class="hljs-attribute">margin-bottom</span>: .<span class="hljs-number">5em</span>;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/static-html-css-gray-background-different-lists.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Style difference between applying to the top level list or the list items</em></p>
<p>And now it's starting to come together, but it kind of just looks like placeholders. So let's animate this to look like it's actually loading.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-css-loading-animation-static/commit/f68cdef36be11311a5cc11a1d39e52ea7e7bb48d">Follow along with the commit!</a></p>
<h3 id="heading-step-3-styling-and-animating-our-loading-class">Step 3: Styling and animating our loading class</h3>
<p>Before actually animating our class, we need something to animate, so let's add a gradient to our <code>.loading</code> class:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.loading</span> {
  <span class="hljs-attribute">color</span>: transparent;
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">linear-gradient</span>(<span class="hljs-number">100deg</span>, #eceff1 <span class="hljs-number">30%</span>, #f6f7f8 <span class="hljs-number">50%</span>, #eceff1 <span class="hljs-number">70%</span>);
}
</code></pre>
<p>This is saying that we want a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient">linear gradient</a> that's tilted at 100 degrees, where we start with <code>#eceff1</code> and fade to <code>#f6f7f8</code> at 30% and back to <code>#eceff1</code> at 70%;</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/static-html-css-gray-background-subtle-gradient.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Subtle gradient background that might look like a glare</em></p>
<p>It's hard to see initially when it's still, it might just look like a glare on your computer! If you'd like to see it before moving on, feel free to play with the colors above to see the gradient.</p>
<p>Now that we have something to animate, we'll first need to create a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes">keyframes</a> rule:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@keyframes</span> loading {
  0% {
    <span class="hljs-attribute">background-position</span>: <span class="hljs-number">100%</span> <span class="hljs-number">50%</span>;
  }
  100% {
    <span class="hljs-attribute">background-position</span>: <span class="hljs-number">0</span> <span class="hljs-number">50%</span>;
  }
}
</code></pre>
<p>This rule when applied will change the background position from starting at 100% of the x-axis to 0% of the x-axis.</p>
<p>With the rule, we can add our <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations">animation</a> property to our <code>.loading</code> class:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.loading</span> {
  <span class="hljs-attribute">color</span>: transparent;
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">linear-gradient</span>(<span class="hljs-number">100deg</span>, #eceff1 <span class="hljs-number">30%</span>, #f6f7f8 <span class="hljs-number">50%</span>, #eceff1 <span class="hljs-number">70%</span>);
  <span class="hljs-attribute">animation</span>: loading <span class="hljs-number">1.2s</span> ease-in-out infinite;
}
</code></pre>
<p>Our animation line is setting the keyframe to <code>loading</code>, telling it to last for 1.2 seconds, setting the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function">timing function</a> to <code>ease-in-out</code> to make it smooth, and tell it to loop forever with <code>infinite</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/static-html-css-gray-background-subtle-gradient.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>No change – it's not animating</em></p>
<p>If you notice though after saving that, it's still not doing anything. The reason for this is we're setting our gradient from one end of the DOM element to the other, so there's nowhere to move!</p>
<p>So let's try also setting a <code>background-size</code> on our <code>.loading</code> class.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.loading</span> {
  <span class="hljs-attribute">color</span>: transparent;
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">linear-gradient</span>(<span class="hljs-number">100deg</span>, #eceff1 <span class="hljs-number">30%</span>, #f6f7f8 <span class="hljs-number">50%</span>, #eceff1 <span class="hljs-number">70%</span>);
  <span class="hljs-attribute">background-size</span>: <span class="hljs-number">400%</span>;
  <span class="hljs-attribute">animation</span>: loading <span class="hljs-number">1.2s</span> ease-in-out infinite;
}
</code></pre>
<p>Now, since our background expands beyond our DOM element (you can't see that part), it has some space to animate with and we get our animation!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/static-html-css-loading-animation.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Our loading animation!</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-css-loading-animation-static/commit/bc4b5ec955a0906fea032edbbaf90f037f76c91b">Follow along with the commit!</a></p>
<h2 id="heading-part-2-using-our-loading-animation-in-a-dynamic-app">Part 2: Using our loading animation in a dynamic app</h2>
<p>Now that we have our loading animation, let's put it into action with a basic example where we fake a loading state.</p>
<p>The trick with actually using this is typically we don't have the actual content available, so in most cases, we have to fake it.</p>
<p>To show you how we can do this, we're going to build a simple <a target="_blank" href="https://reactjs.org/">React</a> app with <a target="_blank" href="https://nextjs.org/">Next.js</a>.</p>
<h3 id="heading-step-1-creating-an-example-react-app-with-nextjs">Step 1: Creating an example React app with Next.js</h3>
<p>Navigate to the directory you want to create your new project in and run:</p>
<pre><code class="lang-shell">yarn create next-app
# or
npm init next-app
</code></pre>
<p>It will prompt you with some options, particularly a name which will determine the directory the project is created in and the type of project. I'm using <code>my-css-loading-animation-dynamic</code> and the "Default Starter App".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/nextjs-new-project.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a new project with Next.js</em></p>
<p>Once installed, navigate into your new directory and start up your development server:</p>
<pre><code>cd [directory]
yarn dev
# or 
npm run dev
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2020/05/nextjs-starting-dev-server.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Starting development server with Next.js</em></p>
<p>Next, let's replace the content in our <code>pages/index.js</code> file. I'm going to derive the content from the previous example, but we'll create it similar to how we might expect it to come from an API. First, let's add our  content as an object above our return statement:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> content = {
  <span class="hljs-attr">header</span>: <span class="hljs-string">`So, how 'bout them Knicks?`</span>,
  <span class="hljs-attr">intro</span>: <span class="hljs-string">`What are their names? I'm Santa Claus! This opera's as lousy as it is brilliant! Your lyrics lack subtlety. You can't just have your characters announce how they feel. That makes me feel angry! Good news, everyone! I've taught the toaster to feel love!`</span>,
  <span class="hljs-attr">list</span>: [
    <span class="hljs-string">`Yes! In your face, Gandhi!`</span>,
    <span class="hljs-string">`So I really am important? How I feel when I'm drunk is correct?`</span>,
    <span class="hljs-string">`Who are those horrible orange men?`</span>
  ]
}
</code></pre>
<p>To display that content, inside <code>&lt;main&gt;</code>, let's replace the content with:</p>
<pre><code class="lang-jsx">&lt;main&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{ content.header }<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{ content.intro }<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    { content.list.map((item, i) =&gt; {
      return (
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{i}</span>&gt;</span>{ item }<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      )
    })}
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
&lt;/main&gt;
</code></pre>
<p>And for the styles, you can copy and paste everything from our Part 1 <code>main.css</code> file into the <code>&lt;style&gt;</code> tags at the bottom of our index page. That will leave us with:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/basic-content-with-nextjs.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Basic content with Next.js</em></p>
<p>With that, we should be back to a similar point we finished at in Part 1 except we're not actively using any of the loading animations yet.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-css-loading-animation-dynamic/commit/365e081522ec07b1754bf360a95b0bc373476c95">Follow along with the commit!</a></p>
<h3 id="heading-step-2-faking-loading-data-from-an-api">Step 2: Faking loading data from an API</h3>
<p>The example we're working with is pretty simple. You'd probably see this coming pre-generated statically, but this helps us create a realistic demo that we can test our loading animation with.</p>
<p>To fake our loading state, we're going to use React's <code>useState</code>, <code>useEffect</code>, and an old fashioned <code>setTimeout</code> to preload some "loading" content, and after the <code>setTimeout</code> finishes, update that content with our actual data. In the meantime, we'll know that we're in a loading state with a separate instance of <code>useState</code>.</p>
<p>First, we need to import our dependencies. At the top of our <code>pages/index.js</code> file, add:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
</code></pre>
<p>Above our <code>content</code> object, let's add some state:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> [loadingState, updateLoadingState] = useState(<span class="hljs-literal">true</span>);
<span class="hljs-keyword">const</span> [contentState, updateContentState] = useState({})
</code></pre>
<p>And in our content, we can update the instances to use that state:</p>
<pre><code class="lang-jsx">&lt;h1&gt;{ contentState.header }&lt;/h1&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{ contentState.intro }<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  { contentState.list.map((item, i) =&gt; {
    return (
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{i}</span>&gt;</span>{ item }<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    )
  })}
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
</code></pre>
<p>Once you save and load that, you'll first notice we get an error because our <code>list</code> property doesn't exist on our <code>contentState</code>, so we can first fix that:</p>
<pre><code class="lang-jsx">{ <span class="hljs-built_in">Array</span>.isArray(contentState.list) &amp;&amp; contentState.list.map(<span class="hljs-function">(<span class="hljs-params">item, i</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{i}</span>&gt;</span>{ item }<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>
  )
})}
</code></pre>
<p>And after that's ready, let's add our <code>setTimeout</code> inside of a <code>useEffect</code> hook to simulate our data loading. Add this under our <code>content</code> object:</p>
<pre><code class="lang-jsx">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    updateContentState(content);
    updateLoadingState(<span class="hljs-literal">false</span>)
  }, <span class="hljs-number">2000</span>);
}, [])
</code></pre>
<p>Once you save and open up your browser, you'll notice that for 2 seconds you don't have any content and then it loads in, basically simulating loading that data asynchronously.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-css-loading-animation-dynamic/commit/f0cada8d696ffe3e983f5efc03dc9d75a2245fe1">Follow along with the commit!</a></p>
<h3 id="heading-step-3-adding-our-loading-animation">Step 3: Adding our loading animation</h3>
<p>Now we can finally add our loading animation. So to do this, we're going to use our loading state we set up using <code>useState</code> and if the content is loading, add our <code>.loading</code>  class to our elements.</p>
<p>Before we do that, instead of individually adding this class to each item in the DOM, it might make more sense to do so using CSS and adding the class to the parent, so let's do that first.</p>
<p>First, update the <code>.loading</code> class to target our elements:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.loading</span> <span class="hljs-selector-tag">h1</span>,
<span class="hljs-selector-class">.loading</span> <span class="hljs-selector-tag">p</span>,
<span class="hljs-selector-class">.loading</span> <span class="hljs-selector-tag">li</span> {
  <span class="hljs-attribute">color</span>: transparent;
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">linear-gradient</span>(<span class="hljs-number">100deg</span>, #eceff1 <span class="hljs-number">30%</span>, #f6f7f8 <span class="hljs-number">50%</span>, #eceff1 <span class="hljs-number">70%</span>);
  <span class="hljs-attribute">background-size</span>: <span class="hljs-number">400%</span>;
  <span class="hljs-attribute">animation</span>: loading <span class="hljs-number">1.2s</span> ease-in-out infinite;
}
</code></pre>
<p>Then we can dynamically add our class to our <code>&lt;main&gt;</code> tag:</p>
<pre><code class="lang-jsx">&lt;main className={loadingState ? <span class="hljs-string">'loading'</span> : <span class="hljs-string">''</span>}&gt;
</code></pre>
<p><em>Note: if you use <a target="_blank" href="https://sass-lang.com/">Sass</a>,  you can manage your loading styles by <a target="_blank" href="https://sass-lang.com/documentation/at-rules/extend">extending</a> the <code>.loading</code> class in the instances you want to use it or create a <a target="_blank" href="https://sass-lang.com/documentation/style-rules/placeholder-selectors">placeholder</a> and extend that!</em></p>
<p>And if you refresh the page, you'll notice it's still just a blank page for 2 seconds!</p>
<p>The issue, is when we load our content, nothing exists inside of our tags that can that would allow the line-height of the elements to give it a height.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-css-collapsed-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>No height when there's no content</em></p>
<p>But we can fix that! Because our <code>.loading</code> class sets our text to transparent, we can simply add the word <code>Loading</code> for each piece of content:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> [contentState, updateContentState] = useState({
  <span class="hljs-attr">header</span>: <span class="hljs-string">'Loading'</span>,
  <span class="hljs-attr">intro</span>: <span class="hljs-string">'Loading'</span>,
  <span class="hljs-attr">list</span>: [
    <span class="hljs-string">'Loading'</span>,
    <span class="hljs-string">'Loading'</span>,
    <span class="hljs-string">'Loading'</span>
  ]
})
</code></pre>
<p><em>Note: We can't use an empty space here because that alone won't provide us with a height when rendered in the DOM.</em></p>
<p>And once you save and reload the page, our first 2 seconds will have a loading state that reflects our content!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-css-loading-animation-1.gif" alt="Image" width="600" height="400" loading="lazy">
<em>HTML &amp; CSS loading animation</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-css-loading-animation-dynamic/commit/5b7b1c40d1eebf97f65c966bb771a5f6787073ea">Follow along with the commit!</a></p>
<h2 id="heading-some-additional-thoughts">Some additional thoughts</h2>
<p>This technique can be used pretty broadly. Being a CSS class makes it nice and easy to add where every you want.</p>
<p>If you're not a fan of setting the <code>Loading</code> text for the loading state, another option is to set a fixed height. The only issue with that is it requires more maintenance for tweaking the CSS to match what the content loading in will look like.</p>
<p>Additionally, this won't be perfect. More often than not, you won't know exactly how much copy you have on a page. The goal is to simulate and hint that there will be content and that it's currently loading.</p>
<h2 id="heading-whats-your-favorite-loading-animation">What's your favorite loading animation?</h2>
<p>Let me know on <a target="_blank" href="https://twitter.com/colbyfayock">Twitter</a>!</p>
<h2 id="heading-join-in-on-the-conversation">Join in on the conversation!</h2>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/freeCodeCamp/status/1264557769547493376"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to add Coronavirus (COVID-19) case statistics to your React map dashboard with Gatsby ]]>
                </title>
                <description>
                    <![CDATA[ Previously, we walked through creating a map that shows an interactive look at Coronavirus (COVID-19) cases per country. How can we extend this with some case statistics to show recent data about the impacts on our world? Author's note: Similar to be... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-coronavirus-covid-19-case-statistics-to-your-map-dashboard-in-gatsby-and-react-leaflet/</link>
                <guid isPermaLink="false">66bee8e6bc07dbcebef938dc</guid>
                
                    <category>
                        <![CDATA[ coronavirus ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Covid-19 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Gatsby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GatsbyJS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leaflet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mapping ]]>
                    </category>
                
                    <category>
                        <![CDATA[ maps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react-leaflet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Wed, 22 Apr 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/coronavirus-mapping-app-2600x1000.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Previously, we walked through creating a map that shows an interactive look at Coronavirus (COVID-19) cases per country. How can we extend this with some case statistics to show recent data about the impacts on our world?</p>
<p><em>Author's note: Similar to before, this dashboard is meant to be a demo and proof of concept for using real world data to build a dashboard. While this data should be accurate per the NovelCOVID API, I would recommend using tools like the <a target="_blank" href="https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6">Johns Hopkins University dashboard</a> for complete and accurate analysis. Stay home and be safe! ❤️</em></p>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-what-do-we-need-before-we-get-started">What do we need before we get started?</a></li>
<li><a class="post-section-overview" href="#heading-step-1-update-how-we-fetch-our-data-and-fetch-the-statistics">Step 1: Update how we fetch our data and fetch the statistics</a></li>
<li><a class="post-section-overview" href="#heading-step-2-adding-statistics-to-our-dashboard">Step 2: Adding statistics to our dashboard</a></li>
<li><a class="post-section-overview" href="#heading-step-3-make-the-data-human-friendly">Step 3: Make the data human friendly</a></li>
<li><a class="post-section-overview" href="#heading-step-4-add-the-last-updated-date">Step 4: Add the Last Updated date</a></li>
<li><a class="post-section-overview" href="#heading-what-can-i-do-next">What can I do next?</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/9bfxeod27fU" 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-are-we-going-to-build">What are we going to build?</h2>
<p>We're going to be extending our <a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-coronavirus-covid-19-dashboard-map-app-with-gatsby-and-leaflet">original map demo</a> with some basic statistics that we can retrieve from the <a target="_blank" href="https://github.com/NovelCOVID/API">NovelCOVID API</a>. To get an idea, here's <a target="_blank" href="https://coronavirus-map-dashboard.netlify.app/">my demo</a> I'm basing this off of.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/coronavirus-covid-19-dashboard-map-stats.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Coronavirus (COVID-19) map demo with dashboard statistics</em></p>
<p>While you're not required to have completed <a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-coronavirus-covid-19-dashboard-map-app-with-gatsby-and-leaflet/">Part 1</a> to apply these concepts, it definitely helps, and it lets you set up a map for your dashboard. If you'd like to start there, which I recommend, check out <a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-coronavirus-covid-19-dashboard-map-app-with-gatsby-and-leaflet/">How to create a Coronavirus (COVID-19) Dashboard &amp; Map App with Gatsby and Leaflet</a> first.</p>
<h2 id="heading-woah-a-mapping-app">Woah, a mapping app?</h2>
<p>Yup. If you haven't played with maps before, don't be discouraged! It's not as bad as you probably think. If you'd rather start with mapping basics, you can  <a target="_blank" href="https://www.freecodecamp.org/news/easily-spin-up-a-mapping-app-in-react-with-leaflet/">read more about how mapping works</a>  first.</p>
<h2 id="heading-what-do-we-need-before-we-get-started">What do we need before we get started?</h2>
<p>For this walkthrough, you pretty much need a React app in some form. I'll be working with the dashboard we previously built in my last walkthrough that includes a <a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-coronavirus-covid-19-dashboard-map-app-with-gatsby-and-leaflet/">map of the cases of the Coronavirus (COVID-19) per country</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/coronavirus-map-tutorial-country-markers.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Coronavirus (COVID-19) map dashboard</em></p>
<p>I recommend starting with the previous tutorial, but if you want to skip the map and start fresh, the easiest way would probably be to use <a target="_blank" href="https://github.com/facebook/create-react-app">Create React App</a>, <a target="_blank" href="https://www.gatsbyjs.org/">Gatsby</a>, or <a target="_blank" href="https://nextjs.org/">Next.js</a>.</p>
<h2 id="heading-step-1-update-how-we-fetch-our-data-and-fetch-the-statistics">Step 1: Update how we fetch our data and fetch the statistics</h2>
<p>To get started with our statistics dashboard, we're going to do a little prep work by changing how we're fetching the data. The goal here, is we're going to wrap our request logic in a reusable way so that we can use it for both our countries data and our new statistics data.</p>
<h3 id="heading-creating-a-new-react-hook-to-fetch-data">Creating a new React hook to fetch data</h3>
<p>Diving in, the first we'll do is create a new <a target="_blank" href="https://reactjs.org/docs/hooks-reference.html">React hook</a> that will serve as how we fetch the data. To get started, create a new file in your hooks directory called <code>useTracker.js</code>  and add a line inside of <code>hooks/index.js</code> to export it:</p>
<pre><code class="lang-js"><span class="hljs-comment">// New file src/hooks/useTracker.js</span>
<span class="hljs-comment">// This will be empty for now</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// Inside hooks/index.js</span>
<span class="hljs-keyword">export</span> { <span class="hljs-keyword">default</span> <span class="hljs-keyword">as</span> useTracker } <span class="hljs-keyword">from</span> <span class="hljs-string">'./useTracker'</span>;
</code></pre>
<p>Inside of our <code>useTracker.js</code> file, we're going to set up our request logic. This is a long file, so make sure you copy and paste the entire thing before we walk through what it does:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">const</span> API_HOST = <span class="hljs-string">'https://corona.lmao.ninja/v2'</span>;

<span class="hljs-keyword">const</span> ENDPOINTS = [
  {
    <span class="hljs-attr">id</span>: <span class="hljs-string">'all'</span>,
    <span class="hljs-attr">path</span>: <span class="hljs-string">'/all'</span>,
    <span class="hljs-attr">isDefault</span>: <span class="hljs-literal">true</span>
  },
  {
    <span class="hljs-attr">id</span>: <span class="hljs-string">'countries'</span>,
    <span class="hljs-attr">path</span>: <span class="hljs-string">'/countries'</span>
  }
]

<span class="hljs-keyword">const</span> defaultState = {
  <span class="hljs-attr">data</span>: <span class="hljs-literal">null</span>,
  <span class="hljs-attr">state</span>: <span class="hljs-string">'ready'</span>
}

<span class="hljs-keyword">const</span> useTracker = <span class="hljs-function">(<span class="hljs-params">{ api = <span class="hljs-string">'all'</span> }</span>) =&gt;</span> {

  <span class="hljs-keyword">const</span> [tracker = {}, updateTracker] = useState(defaultState)

  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchTracker</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">let</span> route = ENDPOINTS.find(<span class="hljs-function">(<span class="hljs-params">{ id } = {}</span>) =&gt;</span> id === api);

    <span class="hljs-keyword">if</span> ( !route ) {
      route = ENDPOINTS.find(<span class="hljs-function">(<span class="hljs-params">{ isDefault } = {}</span>) =&gt;</span> !!isDefault);
    }

    <span class="hljs-keyword">let</span> response;

    <span class="hljs-keyword">try</span> {
      updateTracker(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> {
        <span class="hljs-keyword">return</span> {
          ...prev,
          <span class="hljs-attr">state</span>: <span class="hljs-string">'loading'</span>
        }
      });
      response = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">`<span class="hljs-subst">${API_HOST}</span><span class="hljs-subst">${route.path}</span>`</span>);
    } <span class="hljs-keyword">catch</span>(e) {
      updateTracker(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> {
        <span class="hljs-keyword">return</span> {
          ...prev,
          <span class="hljs-attr">state</span>: <span class="hljs-string">'error'</span>,
          <span class="hljs-attr">error</span>: e
        }
      });
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> { data } = response;

    updateTracker(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> {
        ...prev,
        <span class="hljs-attr">state</span>: <span class="hljs-string">'ready'</span>,
        data
      }
    });

  }

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetchTracker()
  }, [api])

  <span class="hljs-keyword">return</span> {
    fetchTracker,
    ...tracker
  }
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> useTracker;
</code></pre>
<p>Starting from the top:</p>
<ul>
<li>We import our dependencies: we're going to use Reacts <code>useEffect</code>  and <code>useState</code> hooks to manage our requests</li>
<li>We define default constants: we have a base API endpoint for our data, a list of the available endpoints we'll use, and a state object that will store our data</li>
<li>We define our <code>useTracker</code> hook:  our hook includes one argument <code>api</code>  that will allow us to specify which endpoint we'll use to make our request</li>
<li>We set up a state instance: we'll want to keep track of our fetched data, so we create a <code>tracker</code> state instance that we'll be able to update</li>
<li>We created an asynchronous <code>fetchTracker</code> function: we'll use this to make our actual request</li>
<li>Inside our function: we first find the API route and create our URL, update our state instance to a "loading" state, try to make our request, catch any errors if there are any, and finally if the request is successful, we update our state with that data</li>
<li>We trigger our function: using a <code>useEffect</code> hook, we trigger our <code>fetchTracker</code> function to make the request. We only have one dependency of <code>api</code>. This means the function will only fire the first time and any time the <code>api</code> value we pass in changes. We won't be changing that value, but it may be helpful in other instances if you're dynamically changing the API used</li>
<li>We return our tracker: the returned object includes both our <code>tracker</code> data as well as our <code>fetchTracker</code> function that we could use to refetch the data if we'd like</li>
</ul>
<p>And with all of that, we have a brand new hook that will fetch data from the NovelCOVID API.</p>
<h3 id="heading-using-our-new-tracker-hook">Using our new tracker hook</h3>
<p>To make use of this hook, let's jump over to <code>src/pages/index.js</code>, remove our <code>axios</code> import if it's there, and instead import our hook:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useTracker } <span class="hljs-keyword">from</span> <span class="hljs-string">'hooks'</span>;
</code></pre>
<p>With our hook, let's replace our original country data request.  First, add the following to the top of the <code>IndexPage</code> component:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { <span class="hljs-attr">data</span>: countries = [] } = useTracker({
  <span class="hljs-attr">api</span>: <span class="hljs-string">'countries'</span>
});

<span class="hljs-keyword">const</span> hasCountries = <span class="hljs-built_in">Array</span>.isArray(countries) &amp;&amp; countries.length &gt; <span class="hljs-number">0</span>;
</code></pre>
<p>This will let us fetch our country data and let us know if we have any results. Next, let's replace our original request.</p>
<p>Inside of our <code>mapEffect</code> function, let's remove the <code>axios</code> request in addition to the response, the destructured data object, and the <code>hasData</code> constant.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/code-diff-map-effect-countries-data.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Code diff showing update to map effect</em></p>
<p>Then, replace <code>hasData</code> with <code>hasCountries</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">if</span> ( !hasCountries ) <span class="hljs-keyword">return</span>;
</code></pre>
<p>And replace <code>data</code> with <code>countries</code> in the <code>geoJson</code> object where we map our features:</p>
<pre><code class="lang-js">features: countries.map(<span class="hljs-function">(<span class="hljs-params">country = {}</span>) =&gt;</span> {
</code></pre>
<p>At this point, if you hit save and refresh, you shouldn't notice any difference to what you previously had.</p>
<h3 id="heading-add-a-request-for-our-stats">Add a request for our stats</h3>
<p>Now that we are using our <code>useTracker</code> hook to fetch our country data, let's also use that to fetch our stats.</p>
<p>Right next to where we set up our <code>useTracker</code> hook before, let's add another request:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { <span class="hljs-attr">data</span>: stats = {} } = useTracker({
  <span class="hljs-attr">api</span>: <span class="hljs-string">'all'</span>
});
</code></pre>
<p>And if we add a <code>console.log</code> statement under to see what's inside <code>stats</code>:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'stats'</span>, stats);
</code></pre>
<p>We should see our <code>stats</code> data object logged out!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/console-log-coronavirus-stats-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Using console.log to show Coronavirus (COVID-19) statistics</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/fe9d85e57f7474a86d38213676bf62df4b6168a4">Follow along with the commit!</a></p>
<h2 id="heading-step-2-adding-statistics-to-our-dashboard">Step 2: Adding statistics to our dashboard</h2>
<p>Now that we have our data available to use, let's use it!</p>
<p>To get started adding our statistics to the dashboard, let's create a data structure that will allow us to easily configure the data we want to use.</p>
<p>To do this, let's first create a new array called <code>dashboardStats</code> below <code>hasCountries</code> at the top of the page component:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> dashboardStats = [];
</code></pre>
<p>Inside this array, let's add some new objects that specify our data that we're pulling from the <code>stats</code> object we requested. To start, let's try to add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> dashboardStats = [
  {
    <span class="hljs-attr">primary</span>: {
      <span class="hljs-attr">label</span>: <span class="hljs-string">'Total Cases'</span>,
      <span class="hljs-attr">value</span>: stats?.cases
    },
    <span class="hljs-attr">secondary</span>: {
      <span class="hljs-attr">label</span>: <span class="hljs-string">'Per 1 Million'</span>,
      <span class="hljs-attr">value</span>: stats?.casesPerOneMillion
    }
  },
  {
    <span class="hljs-attr">primary</span>: {
      <span class="hljs-attr">label</span>: <span class="hljs-string">'Total Deaths'</span>,
      <span class="hljs-attr">value</span>: stats?.deaths
    },
    <span class="hljs-attr">secondary</span>: {
      <span class="hljs-attr">label</span>: <span class="hljs-string">'Per 1 Million'</span>,
      <span class="hljs-attr">value</span>: stats?.deathsPerOneMillion
    }
  },
  {
    <span class="hljs-attr">primary</span>: {
      <span class="hljs-attr">label</span>: <span class="hljs-string">'Total Tests'</span>,
      <span class="hljs-attr">value</span>: stats?.tests
    },
    <span class="hljs-attr">secondary</span>: {
      <span class="hljs-attr">label</span>: <span class="hljs-string">'Per 1 Million'</span>,
      <span class="hljs-attr">value</span>: stats?.testsPerOneMillion
    }
  }
]
</code></pre>
<p>The reason we're splitting this up into <code>primary</code> and <code>secondary</code> keys, is we're going to use that to differentiate between logically similar stats that we want to style a little bit differently.</p>
<p>_Note: if you're not familiar with the <code>?.</code> syntax, it's called <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">Optional Chaining</a>. This allows us to chain our properties without worrying about if the objects exist. If <code>stats</code> is undefined, it will simply return undefined instead of throwing an error._</p>
<p>With our stats data, let's add the tracker to our map. Let's remove our current <code>&lt;Map&gt;</code> component and include it nested inside our tracker div in the following:</p>
<pre><code class="lang-jsx">&lt;div className=<span class="hljs-string">"tracker"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Map</span> {<span class="hljs-attr">...mapSettings</span>} /&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"tracker-stats"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      { dashboardStats.map(({ primary = {}, secondary = {} }, i) =&gt; {
        return (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">Stat-</span>${<span class="hljs-attr">i</span>}`} <span class="hljs-attr">className</span>=<span class="hljs-string">"tracker-stat"</span>&gt;</span>
            { primary.value &amp;&amp; (
              <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"tracker-stat-primary"</span>&gt;</span>
                { primary.value }
                <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{ primary.label }<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            )}
            { secondary.value &amp;&amp; (
              <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"tracker-stat-secondary"</span>&gt;</span>
                { secondary.value }
                <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{ secondary.label }<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">p</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>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
&lt;/div&gt;
</code></pre>
<p>This code should be immediately following the <code>&lt;Helmet&gt;</code> component if you're following along.</p>
<p>To explain what we're doing:</p>
<ul>
<li>We're creating a "tracker" div that will organize our stats</li>
<li>We move our <code>&lt;Map</code> component inside of this tracker</li>
<li>We create a separate section called "tracker-stats"</li>
<li>Inside of this, we create an unordered list (<code>ul</code>)</li>
<li>Inside of our list, we loop through all of our stats inside <code>dashboardStats</code></li>
<li>For each stat, we create a new list element (<code>li</code>) and include 2 optional paragraphs that includes our primary stat data and our secondary stat data</li>
</ul>
<p>Once we reload our page, we should now see a few stats:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/adding-coronavirus-stats-to-page.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Adding the first statistics to the page</em></p>
<p>Now that we have our stats on our page, let's make them look like they're in a dashboard.</p>
<p>Let's create a new file called <code>_tracker.scss</code> inside of our <code>src/assets/stylesheets/components</code> directory. Once that file is created, additionally add it to the <code>src/assets/stylesheets/components/__components.scss</code> file:</p>
<pre><code class="lang-scss"><span class="hljs-keyword">@import</span> <span class="hljs-string">"tracker"</span>;
</code></pre>
<p>With our new component style file ready to go, let's add some styles into <code>_tracker.scss</code>:</p>
<pre><code class="lang-scss"><span class="hljs-selector-class">.tracker-stats</span> {

  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-variable">$blue-grey-900</span>;
  <span class="hljs-attribute">border-top</span>: solid <span class="hljs-number">1px</span> darken(<span class="hljs-variable">$blue-grey-900</span>, <span class="hljs-number">5</span>);

  <span class="hljs-selector-tag">ul</span> {
    <span class="hljs-attribute">display</span>: grid;
    grid-template-<span class="hljs-attribute">columns</span>: <span class="hljs-number">1</span>fr <span class="hljs-number">1</span>fr <span class="hljs-number">1</span>fr;
    <span class="hljs-attribute">list-style</span>: none;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  }

}

<span class="hljs-selector-class">.tracker-stat</span> {

  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2em</span>;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">padding</span>: .<span class="hljs-number">5em</span>;
  <span class="hljs-attribute">border-right</span>: solid <span class="hljs-number">1px</span> darken(<span class="hljs-variable">$blue-grey-900</span>, <span class="hljs-number">5</span>);
  <span class="hljs-attribute">border-bottom</span>: solid <span class="hljs-number">1px</span> darken(<span class="hljs-variable">$blue-grey-900</span>, <span class="hljs-number">5</span>);

  <span class="hljs-selector-tag">strong</span> {
    <span class="hljs-attribute">font-weight</span>: normal;
    <span class="hljs-attribute">color</span>: <span class="hljs-variable">$blue-grey-300</span>;
  }

}

<span class="hljs-selector-class">.tracker-stat-primary</span> {

  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;

  <span class="hljs-selector-tag">strong</span> {
    <span class="hljs-attribute">display</span>: block;
    <span class="hljs-attribute">font-size</span>: .<span class="hljs-number">5em</span>;
  }

}

<span class="hljs-selector-class">.tracker-stat-secondary</span> {

  <span class="hljs-attribute">font-size</span>: .<span class="hljs-number">5em</span>;
  <span class="hljs-attribute">margin</span>: .<span class="hljs-number">8em</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span>;

  <span class="hljs-selector-tag">strong</span> {
    <span class="hljs-attribute">font-size</span>: .<span class="hljs-number">8em</span>;
    <span class="hljs-attribute">margin-left</span>: .<span class="hljs-number">4em</span>;
  }

}
</code></pre>
<p>Above – we're adding colors and organizational effects, such as using <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout">CSS Grid</a>, to allow our data to be organized in an easy to read way and to look good! We're also making use of some pre-existing colors variables that are used within the project to keep the color use consistent.</p>
<p>Once you save those styles and reload the page, it should look much better:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/adding-coronavirus-case-statistics-to-map-dashboard.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Adding case statistics to the dashboard</em></p>
<p>From here, feel free to add more stats or adjust them to your liking. In the demo I created, I added the stats for active cases, critical cases, and recovered cases. If you'd like to do the same, you can <a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/eb8a28c9e46dc2327ada0df21b250422e55d304c">check out the commit</a>.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/eb8a28c9e46dc2327ada0df21b250422e55d304c">Follow along with the commit!</a></p>
<h2 id="heading-step-3-make-the-data-human-friendly">Step 3: Make the data human friendly</h2>
<p>Now the rest of this walkthrough could be considered optional, but ultimately we want people to be able to read these statistics, right? So let's make the numbers a little more easy to read.</p>
<p>First, let's open our <code>src/lib/util.js</code> file and add this function:</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 * commafy
 * <span class="hljs-doctag">@description </span>Applies appropriate commas to large numbers
 */</span>

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">commafy</span>(<span class="hljs-params">value</span>) </span>{
  <span class="hljs-keyword">let</span> numberString = <span class="hljs-string">`<span class="hljs-subst">${value}</span>`</span>;

  numberString = numberString.split(<span class="hljs-string">''</span>);

  numberString.reverse();

  numberString = numberString.reduce(<span class="hljs-function">(<span class="hljs-params">prev, current, index</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> shouldComma = (index + <span class="hljs-number">1</span>) % <span class="hljs-number">3</span> === <span class="hljs-number">0</span> &amp;&amp; index + <span class="hljs-number">1</span> &lt; numberString.length;
    <span class="hljs-keyword">let</span> updatedValue = <span class="hljs-string">`<span class="hljs-subst">${prev}</span><span class="hljs-subst">${current}</span>`</span>;
    <span class="hljs-keyword">if</span> ( shouldComma ) {
      updatedValue = <span class="hljs-string">`<span class="hljs-subst">${updatedValue}</span>,`</span>;
    }
    <span class="hljs-keyword">return</span> updatedValue;
  }, <span class="hljs-string">''</span>);

  numberString = numberString.split(<span class="hljs-string">''</span>);
  numberString.reverse()
  numberString = numberString.join(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">return</span> numberString;
}
</code></pre>
<p>This function will take a number and turn it into a string with commas. To walk through what it does:</p>
<ul>
<li>Takes in a value as an argument. For our use, this value will most likely be a number.</li>
<li>It converts the value into a string. We'll use this to work with adding commas to our number.</li>
<li>We split that string into an array and reverse it. We want to reverse it because it makes it easier to add our commas depending on the index.</li>
<li>We use the javascript <code>reduce</code> function to recreate our number-string. After every 3 numbers, we want to add a comma.</li>
<li>Once we have our new value with the commas, we want to re-reverse it. So we split it again, reverse the array of characters, and re-join it, which is what we return</li>
</ul>
<p>And now that we have our <code>commafy</code> function, let's use it. Back inside <code>src/pages/index.js</code>, let's import our function at the top of the page:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { commafy } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/util'</span>;
</code></pre>
<p>Then, in our <code>dashboardStats</code> array, let's replace every number value with a ternary expression and function that will convert our number if it's available:</p>
<pre><code class="lang-js">value: stats ? commafy(stats?.cases) : <span class="hljs-string">'-'</span>
</code></pre>
<p>This line checks to see if <code>stats</code> exists. If it does, we <code>commafy</code> the <code>cases</code> value. If it doesn't exist, we return a <code>-</code> to show it's unavailable.</p>
<p>Once we repeat that process for all of our numbers, we can save, reload the page, and see our human friendly numbers!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/coronavirus-dashboard-stats-with-readable-stats.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Formatting the statistics to be human readable</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/90f266c17815239d9d3356d9b9d660915fdc26c2">Follow along with the commit!</a></p>
<h2 id="heading-step-4-add-the-last-updated-date">Step 4: Add the Last Updated date</h2>
<p>Finally, we want to make sure people are staying informed and understand the last time this data was updated. Luckily, our API provides a Last Updated date for us, so let's use it!</p>
<p>At the bottom of our "tracker" <code>div</code> under <code>tracker-stats</code>, let's add the following:</p>
<pre><code class="lang-jsx">&lt;div className=<span class="hljs-string">"tracker-last-updated"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
    Last Updated: { stats?.updated }
  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
&lt;/div&gt;
</code></pre>
<p>This creates a new section where we simply include the <code>updated</code> property from our stats. And if we save and reload the page, we can see the last updated date!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/coronvirus-dashboard-last-updated.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Adding last updated to the dashboard</em></p>
<p>But how could we even understand what that number is, unless you're the computer crawling this blog post? So let's change it to a human readable format like we did with our numbers.</p>
<p>Inside of our <code>src/lib/util.js</code> file, let's add another function:</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 * friendlyDate
 * <span class="hljs-doctag">@description </span>Takes in a date value and returns a friendly version
 */</span>

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">friendlyDate</span>(<span class="hljs-params">value</span>) </span>{
  <span class="hljs-keyword">const</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(value);
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Intl</span>.DateTimeFormat(<span class="hljs-string">'en'</span>, {
    <span class="hljs-attr">year</span>: <span class="hljs-string">'numeric'</span>,
    <span class="hljs-attr">month</span>: <span class="hljs-string">'short'</span>,
    <span class="hljs-attr">day</span>: <span class="hljs-string">'2-digit'</span>,
    <span class="hljs-attr">hour</span>: <span class="hljs-string">'numeric'</span>,
    <span class="hljs-attr">minute</span>: <span class="hljs-string">'numeric'</span>
  }).format(date);
}
</code></pre>
<p>This function creates a new <code>Date</code> object, then uses the javascript <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat">International DateTimeFormat API</a> to convert it into a friendly readable format!</p>
<p>Once that's saved, let's import it next to our <code>commafy</code> function at the top of <code>src/pages/index.js</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { commafy, friendlyDate } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/util'</span>;
</code></pre>
<p>Then we can update our code similar to how we updated our numbers:</p>
<pre><code class="lang-jsx">Last Updated: { stats ? friendlyDate(stats?.updated) : <span class="hljs-string">'-'</span> }
</code></pre>
<p>And if we save and reload, we see it in a human readable way!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/coronvirus-dashboard-last-updated-formatted-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Formatting the last updated date</em></p>
<p>Finally for our "last updated" should look like it fits in with the rest of the dashboard, so let's add a few more styles. Inside of our <code>_tracker.scss</code> file we were working with earlier:</p>
<pre><code class="lang-scss"><span class="hljs-selector-class">.tracker-last-updated</span> {

  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-variable">$blue-grey-900</span>;
  <span class="hljs-attribute">padding</span>: .<span class="hljs-number">8em</span> <span class="hljs-number">0</span>;

  <span class="hljs-selector-tag">p</span> {
    <span class="hljs-attribute">color</span>: <span class="hljs-variable">$blue-grey-300</span>;
    <span class="hljs-attribute">font-size</span>: .<span class="hljs-number">8em</span>;
    <span class="hljs-attribute">text-align</span>: center;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  }

}
</code></pre>
<p>And once we hit save and refresh the browser, we have our dashboard statistics with the last updated time! ?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/coronavirus-dashboard-formatted-styled.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Final dashboard with formatted lasted updated date</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/408286aecb32223c8782eb1539f5563135c75dfb">Follow along with the commit!</a></p>
<h2 id="heading-what-can-i-do-next">What can I do next?</h2>
<h3 id="heading-make-the-marker-tooltip-data-human-friendly">Make the marker tooltip data human friendly</h3>
<p>Now that we have our handy <code>commafy</code> and <code>friendlyDate</code> functions, we can reuse those functions to clean up the data in our country marker popups!</p>
<h3 id="heading-use-the-fetchtracker-function-to-poll-for-updates">Use the fetchTracker function to poll for updates</h3>
<p>Inside of the <code>useTracker</code> hook we created, we exported a function called <code>fetchTracker</code>. This allows us to force a request to the API to fetch new data. To make sure our map stays current even when somebody doesn't refresh the page, we can create a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">timer</a> in javascript to regularly invoke that function to update our dashboard data.</p>
<h3 id="heading-clear-the-map-layers-before-re-adding-the-new-ones">Clear the map layers before re-adding the new ones</h3>
<p>One thing we're currently not doing is cleaning up old layers before adding a new one. The way the map is set up, it just keeps layering them on top. What we can do is before we add all of our new layers, we can clear out the old ones. <a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/cad3b5a6e31a6ae090549c12e40a08fee4db4aa5">Check out this commit</a> to get started!</p>
<h2 id="heading-want-to-learn-more-about-maps">Want to learn more about maps?</h2>
<p>You can check out a few of my other resources to get started:</p>
<ul>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-coronavirus-covid-19-dashboard-map-app-with-gatsby-and-leaflet">How to create a Coronavirus (COVID-19) Dashboard &amp; Map App in React with Gatsby and Leaflet</a> (Part 1 of this post)</li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/04/how-to-set-up-a-custom-mapbox-basemap-style-with-react-leaflet-and-leaflet-gatsby-starter/">How to set up a custom Mapbox basemap style with React Leaflet and Leaflet Gatsby Starter</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/anyone-can-map-inspiration-and-an-introduction-to-the-world-of-mapping">Anyone Can Map! Inspiration and an introduction to the world of mapping</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-summer-road-trip-mapping-app-with-gatsby-and-leaflet">How to Create a Summer Road Trip Mapping App with Gatsby and Leaflet</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2019/12/create-your-own-santa-tracker-with-gatsby-and-react-leaflet/">How to Create your own Santa Tracker with Gatsby and React Leaflet</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/easily-spin-up-a-mapping-app-in-react-with-leaflet/">How to build a mapping app in React the easy way with Leaflet</a></li>
</ul>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Custom React Hook and Publish it to npm ]]>
                </title>
                <description>
                    <![CDATA[ Hooks are a handy addition to the React API that allow us to organize some of our logic and state in function components. How can we build a custom hook and share it with the rest of the world? What are hooks? Why are custom hooks cool? What are we ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-custom-react-hook-and-publish-it-to-npm/</link>
                <guid isPermaLink="false">66b8e34f682e4a25eed261a0</guid>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm scripts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Yarn ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 14 Apr 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/Custom-React-Hooks-Book-Cover--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hooks are a handy addition to the React API that allow us to organize some of our logic and state in function components. How can we build a custom hook and share it with the rest of the world?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-hooks">What are hooks?</a></li>
<li><a class="post-section-overview" href="#heading-why-are-custom-hooks-cool">Why are custom hooks cool?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-make">What are we going to make?</a></li>
<li><a class="post-section-overview" href="#heading-step-0-naming-your-hook">Step 0: Naming your hook</a></li>
<li><a class="post-section-overview" href="#heading-step-1-setting-up-your-project">Step 1: Setting up your project</a></li>
<li><a class="post-section-overview" href="#heading-step-2-writing-your-new-react-hook">Step 2: Writing your new React Hook</a></li>
<li><a class="post-section-overview" href="#heading-step-3-using-your-react-hook-in-an-example">Step 3: Using your React hook in an example</a></li>
<li><a class="post-section-overview" href="#heading-step-4-compiling-your-react-hook-and-example">Step 4: Compiling your React hook and Example</a></li>
<li><a class="post-section-overview" href="#heading-step-5-publishing-your-react-hook-to-npm">Step 5: Publishing your React hook to npm</a></li>
<li><a class="post-section-overview" href="#heading-more-resources-about-hooks">More resources about hooks</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Q0xVnRanXVk" 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-are-hooks">What are hooks?</h2>
<p>React <a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">hooks</a> in simple terms are functions. When you include them in your component or within another hook, they allow you to make use of React internals and parts of the React lifecycle with native hooks like <code>useState</code> and <code>useEffect</code>.</p>
<p>I don’t plan on doing a deep dive about hooks, but you can <a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">check out a quick introduction</a> with an example of <code>useState</code> as well as <a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">the intro from the React team</a>.</p>
<h2 id="heading-why-are-custom-hooks-cool">Why are custom hooks cool?</h2>
<p>The great thing about creating custom hooks is they allow you to abstract logic for your components making it easier to reuse across multiple components in your app.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/hook-example-use-counter-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Hook diagram example for useCounter</em></p>
<p>For instance, if you wanted to create a simple counter where you use React’s state to manage the current count. Instead of having the same <code>useState</code> hook in each component file, you can create that logic once in a <code>useCounter</code> hook, making it easier to maintain, extend, and squash bugs if they come up.</p>
<h2 id="heading-what-are-we-going-to-make">What are we going to make?</h2>
<p>For the purposes of this article, we’re going to keep it simple with a basic hook. Typically, you might use a hook because rather than a typical function, you use other native hooks that are required to be used within React function components. We’re going to stick with some basic input and output to keep things simple.</p>
<p>We’re going to recreate this custom <a target="_blank" href="https://github.com/colbyfayock/use-placecage">Placecage hook</a> I made, that allows you to easily generate image URLs that you can use as placeholder images.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/nic-cage-excited.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Nic Cage excited</em></p>
<p>If you’re not familiar, <a target="_blank" href="https://www.placecage.com/">Placecage</a> is an API that allows you to generate pictures of Nic Cage as placeholder images for your website. Silly? Yes. Fun? Absolutely!</p>
<p>But if you’re not a fan of Nic's work, you can just as easily swap in the URL for <a target="_blank" href="https://placeholder.com/">Fill Murray</a> which uses pictures of Bill Murray or <a target="_blank" href="https://placeholder.com/">placeholder.com</a> which generates simple solid color background with text that shows the size of the image.</p>
<h2 id="heading-step-0-naming-your-hook">Step 0: Naming your hook</h2>
<p>Before we jump in to our actual code, our ultimate goal is to publish this hook. If that’s not your goal, you can skip this step, but for publishing, we’ll want to create a name for our hook.</p>
<p>In our case, our hook name will be <code>usePlaceCage</code>. Now with that in mind, we have 2 formats of our name — one in camelCase format and one in snake-case format.</p>
<ul>
<li><strong>camelCase:</strong> usePlaceCage</li>
<li><strong>snake-case:</strong> use-placecage</li>
</ul>
<p>The camelCase format will be used for the actual hook function, where the snake-case name will be used for the package name and some of the folders. When creating the name, keep in mind that the package name must be unique. If a package with the same name exists on <a target="_blank" href="https://www.npmjs.com/">npmjs.com</a> already, you won't be able to use it.</p>
<p>If you don’t already have a name, it's okay! You can just use your own name or something you can think of, it doesn’t really matter too much as really we're just trying to learn how to do this. If it were me for instance, I would use:</p>
<ul>
<li><strong>camelCase:</strong> useColbysCoolHook</li>
<li><strong>snake-case:</strong> use-colbyscoolhook</li>
</ul>
<p>But just to clarify, for the rest of our example, we’re going to stick with <code>usePlaceCage</code> and <code>use-placecage</code>.</p>
<h2 id="heading-step-1-setting-up-your-project">Step 1: Setting up your project</h2>
<p>Though you can set up your project however you’d like, we’re going to walk through building a new hook from <a target="_blank" href="https://github.com/colbyfayock/use-custom-hook">this template</a> I created.</p>
<p>The hope here, is that we can take out some of the painful bits of the process and immediately get productive with our custom hook. Don’t worry though, I’ll explain what’s going on along the way.</p>
<p>The requirements here are <a target="_blank" href="https://git-scm.com/">git</a> and <a target="_blank" href="https://yarnpkg.com/">yarn</a> as it helps provide tools that make it easy to scaffold this template, such as using the workspaces feature to allow easy npm scripts to manage the code from the root of the project. If either of those are a dealbreaker, you can try downloading the repo via the download link and update it as needed.</p>
<h3 id="heading-cloning-the-hook-template-from-git">Cloning the hook template from git</h3>
<p>To start, let’s clone the repository from Github. In the command below, you should replace <code>use-my-custom-hook</code> with the name of your hook, such as <code>use-cookies</code> or <code>use-mooncake</code>.</p>
<pre><code class="lang-shell">git clone https://github.com/colbyfayock/use-custom-hook use-my-custom-hook
cd use-my-custom-hook
</code></pre>
<p>Once you clone and navigate to that folder, you should now see 2 directories – an <code>example</code> directory and a <code>use-custom-hook</code> directory.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/cloning-use-custom-hook-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Cloning use-custom-hook</em></p>
<p>This will give you a few things to get started:</p>
<ul>
<li>A hook directory that will include the source for our hook</li>
<li>Build scripts that compile our hook with <a target="_blank" href="https://babeljs.io/">babel</a></li>
<li>An example page that imports our hook and creates a simple demo page with <a target="_blank" href="https://nextjs.org/">next.js</a></li>
</ul>
<h3 id="heading-running-the-hook-setup-scripts">Running the hook setup scripts</h3>
<p>After we successfully clone the repo, we want to run the setup scripts which install dependencies and update the hook to the name we want.</p>
<pre><code class="lang-shell">yarn install &amp;&amp; yarn setup
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/setting-up-new-hook-template.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Setting up a new hook from the use-custom-hook template</em></p>
<p>When the setup script runs, it will do a few things:</p>
<ul>
<li>It will ask you for your name – this is used to update the LICENSE and the package's author name</li>
<li>It will ask you for your hook's name in 2 variations – camelCase and snake-case - this will be used to update the name of the hook throughout the template and move files with that name to the correct location</li>
<li>It will reset git – it will first remove the local .git folder, which contains the history from my template and reinitialize git with a fresh commit to start your new history in</li>
<li>Finally, it will remove the setup script directory and remove the package dependencies that were only being used by those scripts</li>
</ul>
<h3 id="heading-starting-the-development-server">Starting the development server</h3>
<p>Once the setup scripts finish running, you'll want to run:</p>
<pre><code class="lang-shell">yarn develop
</code></pre>
<p>This runs a watch process on the hook source, building the hook locally each time a source file is changed, and running the example app server, where you can test the hook and make changes to the example pages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/custom-hook-development-server.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Starting up the use-custom-hook development server</em></p>
<p>With this all ready, we can get started!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commits/master">Follow along with the commit!</a></p>
<h2 id="heading-step-2-writing-your-new-react-hook">Step 2: Writing your new React Hook</h2>
<p>At this point, you should now have a new custom hook where you can make it do whatever you'd like. But since we're going to walk through rebuilding the <a target="_blank" href="https://github.com/colbyfayock/use-placecage">usePlaceCage</a> hook, let's start there.</p>
<p>The usePlaceCage hook does 1 simple thing from a high level view – it takes in a configuration object and returns a number of image URLs that you can then use for your app.</p>
<p>Just as a reminder, any time I mention <code>usePlaceCage</code> or <code>use-placecage</code>, you should use the hook name that you set up before.</p>
<h3 id="heading-a-little-bit-about-placecagecom">A little bit about placecage.com</h3>
<p>Placecage.com is a placeholder image service that does 1 thing. It takes a URL with a simple configuration and returns an image... of Nic Cage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/placecage-website.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>placecage.com</em></p>
<p>From the simplest use, the service uses a URL pattern as follows:</p>
<pre><code>https:<span class="hljs-comment">//www.placecage.com/200/300</span>
</code></pre><p>This would return an image with a width of 200 and height of 300.</p>
<p>Optionally, you can pass an additional URL parameter that defines the type of image:</p>
<pre><code>https:<span class="hljs-comment">//www.placecage.com/gif/200/300</span>
</code></pre><p>In this particular instance, our type is <code>gif</code>, so we'll receive a gif.</p>
<p>The different types available to use are:</p>
<ul>
<li>Nothing: calm</li>
<li><code>g</code>: gray</li>
<li><code>c</code>: crazy</li>
<li><code>gif</code>: gif</li>
</ul>
<p>We'll use this to define how we set up configuration for our hook.</p>
<h3 id="heading-defining-our-core-generator-function">Defining our core generator function</h3>
<p>To get started, we're going to copy over a function at the bottom of our <code>use-placecage/src/usePlaceCage.js</code> file, which allows us to generate an image URL, as well as a few constant definitions that we'll use in that function.</p>
<p>First, let's copy over our constants to the top of our <code>usePlaceCage.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> PLACECAGE_HOST = <span class="hljs-string">'https://www.placecage.com/'</span>;
<span class="hljs-keyword">const</span> TYPES = {
  <span class="hljs-attr">calm</span>: <span class="hljs-literal">null</span>,
  <span class="hljs-attr">gray</span>: <span class="hljs-string">'g'</span>,
  <span class="hljs-attr">crazy</span>: <span class="hljs-string">'c'</span>,
  <span class="hljs-attr">gif</span>: <span class="hljs-string">'gif'</span>
};
<span class="hljs-keyword">const</span> DEFAULT_TYPE = <span class="hljs-string">'calm'</span>;
<span class="hljs-keyword">const</span> ERROR_BASE = <span class="hljs-string">'Failed to place Nick'</span>;
</code></pre>
<p>Here we:</p>
<ul>
<li>Define a host, which is the base URL of our image service.</li>
<li>Define the available types, which we'll use in the configuration API. We set <code>calm</code> to <code>null</code>, because it's the default value which you get by not including it at all</li>
<li>Our default type will be <code>calm</code></li>
<li>And we set an error base which is a consistent message when throwing an error</li>
</ul>
<p>Then for our function, let's copy this at the bottom of our <code>usePlaceCage.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateCage</span>(<span class="hljs-params">settings</span>) </span>{
  <span class="hljs-keyword">const</span> { type = DEFAULT_TYPE, width = <span class="hljs-number">200</span>, height = <span class="hljs-number">200</span>, count = <span class="hljs-number">1</span> } = settings;
  <span class="hljs-keyword">const</span> config = [];

  <span class="hljs-keyword">if</span> ( type !== DEFAULT_TYPE &amp;&amp; TYPES[type] ) {
    config.push(TYPES[type]);
  }

  config.push(width, height);

  <span class="hljs-keyword">if</span> ( <span class="hljs-built_in">isNaN</span>(count) ) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`<span class="hljs-subst">${ERROR_BASE}</span>: Invalid count <span class="hljs-subst">${count}</span>`</span>);
  }

  <span class="hljs-keyword">return</span> [...new <span class="hljs-built_in">Array</span>(count)].map(<span class="hljs-function">() =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${PLACECAGE_HOST}</span><span class="hljs-subst">${config.join(<span class="hljs-string">'/'</span>)}</span>`</span>);
}
</code></pre>
<p>Walking through this code:</p>
<ul>
<li>We define a <code>generateCage</code> function which we'll use to generate our image URL</li>
<li>We take in a settings object as an argument, which defines the configuration of our image URL. We'll be using the same parameters as we saw in our placecage.com URL</li>
<li>We destructure those settings to make them available for us to use</li>
<li>We have a few defaults here just to make it easier. Our default <code>type</code> will be defined by <code>DEFAULT_TYPE</code> along with a default width, height, and number of results we want to return</li>
<li>We create a <code>config</code> array. We'll use this  to append all of the different configuration objects in our URL and finally join them together with a <code>/</code> essentially making a URL</li>
<li>Before we push our config to that array, we check if it's a valid argument, by using the <code>TYPES</code> object to check against it. If it's valid, we push it to our config array</li>
<li>We then push our width and height</li>
<li>We do some type checking, if we don't have a valid number as the <code>count</code>, we throw an error, otherwise we'll get incorrect results</li>
<li>Finally, we return a new array with the number of results requested, mapped to a URL creator, which uses <code>PLACECAGE_HOST</code> as our defined base URL, and with our config array joined by <code>/</code></li>
</ul>
<p>And if we were to test this function, it would look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> cage = generateCage({
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
});

<span class="hljs-built_in">console</span>.log(cage); <span class="hljs-comment">// ['https://www.placecage.com/gif/500/500', 'https://www.placecage.com/gif/500/500']</span>
</code></pre>
<h3 id="heading-using-our-function-in-the-hook">Using our function in the hook</h3>
<p>So now that we have our generator function, let's actually use it in our hook!</p>
<p>Inside of the <code>usePlaceCage</code> function in the <code>use-placecage/src/usePlaceCage.js</code> file, we can add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">usePlaceCage</span> (<span class="hljs-params">settings = {}</span>) </span>{
  <span class="hljs-keyword">return</span> generateCage(settings);
}
</code></pre>
<p>What this does it uses our generator function, takes in the settings that were passed into the hook, and returns that value from the hook.</p>
<p>Similar to our previous use example, if we were to use our hook, it would look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> cage = usePlaceCage({
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
});

<span class="hljs-built_in">console</span>.log(cage); <span class="hljs-comment">// ['https://www.placecage.com/gif/500/500', 'https://www.placecage.com/gif/500/500']</span>
</code></pre>
<p>At this point, it does the same thing!</p>
<p>So now we have our hook, it serves as a function to generate image URLs for the placecage.com service. How can we actually use it?</p>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commit/a4d4d3c3565759031c29d00faf731ac4c236a1fd">Follow along with the commit!</a></p>
<h2 id="heading-step-3-using-your-react-hook-in-an-example">Step 3: Using your React hook in an example</h2>
<p>The good news about our template, is it already includes an example app that we can update to easily make use of our hook to both test and provide documentation for those who want to use it.</p>
<h3 id="heading-setting-up-the-hook">Setting up the hook</h3>
<p>To get started, let's open up our <code>example/pages/index.js</code> file. Inside of this file you'll see the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> hookSettings = {
  <span class="hljs-attr">message</span>: <span class="hljs-string">'Hello, custom hook!'</span>
}

<span class="hljs-keyword">const</span> { message } = usePlaceCage(hookSettings);
</code></pre>
<p>This snippet is what was used by default in the template just for a proof of concept, so let's update that. We're going to use the same exact configuration as we did in Step 2:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> hookSettings = {
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
}

<span class="hljs-keyword">const</span> cage = usePlaceCage(hookSettings);
</code></pre>
<p>Again, we set up our settings object with the configuration for our hook and invoke our hook and set the value to the <code>cage</code> constant.</p>
<p>If we now console log that value our to our dev tools, we can see it working!</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'cage'</span>, cage);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/console-log-cage-array.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Using console.log to show the cage value</em></p>
<p><em>Note: If you get an error here about <code>message</code>, you  can comment that our or remove it under the Examples section.</em></p>
<h3 id="heading-updating-the-example-with-our-new-hook-configuration">Updating the example with our new hook configuration</h3>
<p>If you scroll down to the Examples section, you'll notice that we have the same default <code>hookSettings</code> as above, so let's update that again to make sure our example is accurate.</p>
<pre><code class="lang-jsx">{<span class="hljs-string">`const hookSettings = {
  type: 'gif',
  width: 500,
  height: 500,
  count: 2
}

const cage = usePlaceCage(hookSettings);`</span>}
</code></pre>
<p>You'll also notice that we're no longer using the <code>message</code> variable. If you didn't remove it in the last step, we can now replace it under the Output heading with:</p>
<pre><code class="lang-jsx">&lt;p&gt;
  { <span class="hljs-built_in">JSON</span>.stringify(cage) }
&lt;/p&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
  { cage.map((img, i) =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">img-</span>${<span class="hljs-attr">i</span>}`} <span class="hljs-attr">width</span>=<span class="hljs-string">{200}</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{img}</span> /&gt;</span>)}
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre>
<p>We're doing 2 things here:</p>
<ul>
<li>Instead of showing the variable itself, we wrap it with <code>JSON.stringify</code> so that we can show the contents of the array</li>
<li>We also use the <code>map</code> function to loop over our image URLs in the <code>cage</code> constant and create a new image element for each. This let's us preview the output instead of just seeing the values</li>
</ul>
<p>And once you save and open your browser, you should now see your updated examples and output!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/custom-hook-example-page.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Custom hook example page</em></p>
<h3 id="heading-other-things-you-can-do-on-that-page">Other things you can do on that page</h3>
<p>Before moving on, you can also update a few other things that will be important for your hooks page:</p>
<ul>
<li>Update the <strong>How to use</strong> section with instructions</li>
<li>Add additional examples to make it easier for people to know what to do</li>
</ul>
<p>A  few things are also automatically pulled in from the <code>use-placecage/package.json</code> file. You can either update them there to make it easier to maintain or you can replace them in the example page:</p>
<ul>
<li><code>name</code>: Is used at the <code>&lt;h1&gt;</code> of the page</li>
<li><code>description</code>: Is used at the description under the <code>&lt;h1&gt;</code></li>
<li><code>repository.url</code>: Used to include a link to the repository</li>
<li><code>author</code>: The <code>name</code> and <code>url</code> are used to include a link at the bottom of the page</li>
</ul>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commit/71ae57b562ad814d0ce862c22e247aa8c450b6cf">Follow along with the commit!</a></p>
<h2 id="heading-step-4-compiling-your-react-hook-and-example">Step 4: Compiling your React hook and Example</h2>
<p>The way we can make our hook work easily as an npm module is to compile it for others to use. We're using babel to do this.</p>
<p>Though the publish process already does this for us automatically with the <code>prepublishOnly</code> script in <code>use-placecage/package.json</code>, we can manually compile our hook using the <code>yarn build</code> command from the root of the project.</p>
<p>Along with compiling the hook, running <code>yarn build</code> will also compile the example page, allowing you to upload it wherever you'd like. After running that command, you should see an output of static HTML files in the <code>example/out</code> directory.</p>
<p>If you're looking for a recommendation, <a target="_blank" href="https://www.netlify.com/">Netlify</a> makes it easy to connect your <a target="_blank" href="https://github.com/">Github</a> account and deploy the static site.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/netlify-deployment-setup.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Deployment setup in Netlify</em></p>
<p><a target="_blank" href="https://use-my-custom-hook.netlify.com/">See the demo site deployed to Netlify!</a></p>
<h2 id="heading-step-5-publishing-your-react-hook-to-npm">Step 5: Publishing your React hook to npm</h2>
<p>Finally, if you're happy with your hook, it's time to publish!</p>
<p>npm makes this part really easy. The only prerequisite you need to have an npm account. With that account, let's log in:</p>
<pre><code class="lang-shell">npm login
</code></pre>
<p>Which will prompt you for your login credentials.</p>
<p>Next, let's navigate to our hook's directory, as our package configuration is there under <code>use-placecage/package.json</code>:</p>
<pre><code class="lang-shell">cd use-placecage
</code></pre>
<p>Then, we can simply publish!</p>
<pre><code class="lang-shell">npm publish
</code></pre>
<p>Keep in mind, that each package name needs to be unique. If you used <code>use-placecage</code>, it's already taken... by me. ?</p>
<p>But if you're successful, npm should build your hook and upload it to the package registry!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/publishing-npm-package.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Publishing an npm package</em></p>
<p>It will then be available on npm with the following pattern:</p>
<pre><code>https:<span class="hljs-comment">//www.npmjs.com/package/[package-name]</span>
</code></pre><p>So for <code>use-placeage</code>, it's available here: <a target="_blank" href="https://www.npmjs.com/package/use-placecage">https://www.npmjs.com/package/use-placecage</a></p>
<h2 id="heading-we-now-have-a-custom-hook">We now have a custom hook!</h2>
<p>Yay ? if you followed along, you should now have created a custom hook and published it to npm.</p>
<p>Though this was a silly example using placecage.com, it gives us a good idea of how we can easily set this up.</p>
<p>You'll also notice that this specific example wasn't the best use case for a hooks, where we could have simply used a function. Typically, we'll want to use custom hooks to wrap functionality that can only live inside a React component, such as <code>useState</code>. To learn more about that, you can read one of my other <a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">articles about custom hooks</a>.</p>
<p>However, this gave us a good basis to talk through the creation and configuration of our new hook!</p>
<h2 id="heading-more-resources-about-hooks">More resources about hooks</h2>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">How to destructure the fundamentals of React Hooks</a> (freecodecamp.org)</li>
<li><a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">Introducing Hooks</a> (reactjs.org)</li>
<li><a target="_blank" href="https://reactjs.org/docs/hooks-reference.html">Hooks API Reference</a> (reactjs.org)</li>
</ul>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to set up a custom Mapbox basemap style with React Leaflet and Leaflet Gatsby Starter ]]>
                </title>
                <description>
                    <![CDATA[ Building maps can be pretty powerful, but often you’re stuck with open source options for the map imagery that might not help the readability of your data. How can we leverage Mapbox’s tile APIs to add a custom basemap to our React Leaflet app? What... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-a-custom-mapbox-basemap-with-gatsby-and-react-leaflet/</link>
                <guid isPermaLink="false">66b8e36647c23b7ae1ad0bdb</guid>
                
                    <category>
                        <![CDATA[ create-react-app ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Gatsby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GatsbyJS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JAMstack ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leaflet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mapbox ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mapping ]]>
                    </category>
                
                    <category>
                        <![CDATA[ maps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react-leaflet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Wed, 08 Apr 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-basemap-react-leaflet-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building maps can be pretty powerful, but often you’re stuck with open source options for the map imagery that might not help the readability of your data. How can we leverage Mapbox’s tile APIs to add a custom basemap to our React Leaflet app?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-mapbox">What is Mapbox?</a></li>
<li><a class="post-section-overview" href="#heading-part-1-creating-a-custom-mapbox-style">Part 1: Creating a custom Mapbox style</a></li>
<li><a class="post-section-overview" href="#heading-part-2-adding-a-custom-tilelayer-to-react-leaflet">Part 2: Adding a custom TileLayer to React Leaflet</a></li>
<li><a class="post-section-overview" href="#heading-part-3-adding-a-custom-basemap-to-gatsby-starter-leaflet">Part 3: Adding a custom basemap to Gatsby Starter Leaflet</a></li>
<li><a class="post-section-overview" href="#heading-securing-your-mapbox-key">Securing your Mapbox key</a></li>
<li><a class="post-section-overview" href="#heading-want-to-learn-more-about-maps">Want to learn more about maps?</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/KcPJr1b_rv0" 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-are-we-going-to-build">What are we going to build?</h2>
<p>We’re going to walk through creating a new basic <a target="_blank" href="https://www.mapbox.com/mapbox-studio/">Mapbox style</a> in our <a target="_blank" href="https://www.mapbox.com/">Mapbox</a> account. Once created, we’re going to use their <a target="_blank" href="https://docs.mapbox.com/api/maps/">Map API</a> to add a custom basemap to our <a target="_blank" href="https://react-leaflet.js.org/">React Leaflet</a> app.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/gatsby-starter-leaflet-with-mapbox-tilelayer.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Gatsby Starter Leaflet with Mapbox basemap</em></p>
<p>For our map, we’re going to use this <a target="_blank" href="https://github.com/colbyfayock/gatsby-starter-leaflet">Leaflet Gatsby Starter</a> I created that will allow you to easily spin up a new mapping app. Before we spin that up though, I’ll walk you through how to add it using only React Leaflet components.</p>
<h2 id="heading-a-mapping-app">A mapping app?</h2>
<p>Yup! Maps are used all around the world to study datasets for geographic locations. They're important tools for scientists and others that are trying to help the world.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/coronavirus-map-dashboard-demo.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Coronavirus (COVID-19) custom map</em></p>
<p>If you want to learn more about building a map and adding data to it, you can check out some of <a target="_blank" href="https://www.freecodecamp.org/news/author/colbyfayock/">my other articles</a> first such as creating a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-coronavirus-covid-19-dashboard-map-app-in-react-with-gatsby-and-leaflet/">Coronavirus (COVID-19) map</a> or a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-summer-road-trip-mapping-app-with-gatsby-and-leaflet/">Summer Road Trip map</a> as well as a little bit of inspiration about why <a target="_blank" href="https://www.freecodecamp.org/news/anyone-can-map-inspiration-and-an-introduction-to-the-world-of-mapping/">Anyone Can Map</a>.</p>
<h2 id="heading-what-is-mapbox">What is Mapbox?</h2>
<p>Mapbox is a mapping platform that allows its customers to create custom mapping solutions. They also leverage a variety of APIs that provide powerful capabilities for building map features.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-homepage.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.mapbox.com/">mapbox.com</a></em></p>
<p>For our purposes, we’re going to utilize their Map API, specifically their Static Tiles API, to serve a custom map style that we create.</p>
<h2 id="heading-part-1-creating-a-custom-mapbox-style">Part 1: Creating a custom Mapbox style</h2>
<p>To get the look and feel that we want for our map, it’s important to have a basemap that helps make our data present itself without distractions. Plus, sometimes it’s fun to have a custom map.</p>
<h3 id="heading-mapbox-account">Mapbox account</h3>
<p>The first thing we’ll need to set up our custom Mapbox style is to have an account. I'm not going to walk you through that process, but you can head over to <a target="_blank" href="https://www.mapbox.com/">Mapbox’s website</a> where you can sign up for free: <a target="_blank" href="https://www.mapbox.com/">mapbox.com</a></p>
<h3 id="heading-creating-a-new-custom-style">Creating a new custom style</h3>
<p>Creating a new style in Mapbox isn’t as hard as it sounds. While it can get really complex if you want something unique, we can copy one of Mapbox’s default styles to get started.</p>
<p>First, head over to Mapbox’s <a target="_blank" href="https://studio.mapbox.com/">Studio dashboard</a> by clicking your account link in the top right corner when logged in.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-studio.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Mapbox Studio</em></p>
<p>Once we’re on our Studio dashboard, we want to select the New Style button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-studio-new-style.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Create a new style in Mapbox Studio</em></p>
<p>After clicking the button, a modal will pop up allowing you to choose a template. You can choose whatever you want here, but I’m going to choose Monochrome with a variation of Dark. And after you’ve selected your template, click the Customize button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-studio-new-style-choose-template.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Select and customize a template for a new style in Mapbox Studio</em></p>
<p>And now we’re dropped into our customization UI.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-customize-style.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Mapbox customize style UI</em></p>
<p>From here, you can really do what you’d like. There are a ton of options to customize your map. It’s a little complex to try to dig in here, but <a target="_blank" href="https://docs.mapbox.com/studio-manual/overview/">Mapbox provides some resources</a> to try to help you get productive.</p>
<h3 id="heading-generating-a-mapbox-token">Generating a Mapbox token</h3>
<p>Once you’re happy with your new style and everything’s published, we want to generate a token that we’ll use for providing access to our Map.</p>
<p>Head on over to the Account section of the Mapbox dashboard.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-account.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a new token in Mapbox</em></p>
<p>Mapbox provides you with a “default” token that you can use in your applications. You're free to use this, but I recommend creating a new token that you can provide a unique name, that way if you ever blow past the <a target="_blank" href="https://www.mapbox.com/pricing/">free tier</a> of Mapbox, you’ll be able to track your usage.</p>
<p>Additionally, it’s best to keep a separate token for each application, that way you can easily rotate an individual key, without having to update every application using it.</p>
<p>Once you click Create a token, you can set up the key how you’d like, with the scopes and permissions you choose, but for our purposes, you can leave all of the Public scopes checked for our map, which they do by default.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-create-token.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Create a new access token in Mapbox</em></p>
<h3 id="heading-configuring-our-custom-endpoint">Configuring our custom endpoint</h3>
<p>For this tutorial, we’re going to use <a target="_blank" href="https://docs.mapbox.com/api/maps/#static-tiles">Mapbox’s Static Tiles service</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-static-tiles-map-api.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Mapbox Static Tiles Maps API</em></p>
<p>Our endpoint will look like the following:</p>
<pre><code>https:<span class="hljs-comment">//api.mapbox.com/styles/v1/{username}/{style_id}/tiles/256/{z}/{x}/{y}@2x?access_token={access_token}</span>
</code></pre><p>There are a few parameters here we need to understand:</p>
<ul>
<li>username: this will be your Mapbox account’s username</li>
<li>style_id: this will be the ID of the style you created before</li>
<li>z, x, y: these are parameters that Leaflet programmatically swaps out, so we want to leave them as is</li>
<li>access_token: this is the Mapbox key you created above</li>
</ul>
<p>To find your username and style ID, we can use the Style URL for our new Mapbox style to get those values.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/mapbox-studio-style-url.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Finding the Style URL in Mapbox Studio</em></p>
<p>In my example, my Style URL looks like:</p>
<pre><code>mapbox:<span class="hljs-comment">//styles/colbyfayock/ck8lryjfq0jdo1ip9ctmuhc6p</span>
</code></pre><p><code>colbyfayock</code> is my username and <code>ck8lryjfq0jdo1ip9ctmuhc6p</code> is my style ID.</p>
<p>And once I update my endpoint parameters, the final tilepoint URL will look like:</p>
<pre><code>https:<span class="hljs-comment">//api.mapbox.com/styles/v1/colbyfayock/ck8lryjfq0jdo1ip9ctmuhc6p/tiles/256/{z}/{x}/{y}@2x?access_token=MYACCESSTOKEN</span>
</code></pre><h2 id="heading-part-2-adding-a-custom-tilelayer-to-react-leaflet">Part 2: Adding a custom TileLayer to React Leaflet</h2>
<p>When building a map with React Leaflet, your main component will be a <code>&lt;Map&gt;</code> that wraps the entirety of the app. This is what sets up your <a target="_blank" href="https://leafletjs.com/reference-1.6.0.html#map-example">Map instance</a> for <a target="_blank" href="https://leafletjs.com/">Leaflet</a>.</p>
<p>For our purposes here, we’re going to use the example on the <a target="_blank" href="https://react-leaflet.js.org/">React Leaflet homepage</a> as our starting point.</p>
<h3 id="heading-react-leaflet-tilelayer-component">React Leaflet TileLayer Component</h3>
<p>Inside of your <code>&lt;Map&gt;</code> component you include a <code>&lt;TileLayer&gt;</code> component, which defines the imagery of the world that you base your map upon.</p>
<p>The example on the React Leaflet homepage uses a public version of <a target="_blank" href="https://www.openstreetmap.org/">OpenStreetMap</a> as their TileLayer, which is an open source map project created and updated by people all around the world.</p>
<pre><code class="lang-react">&lt;Map center={position} zoom={13}&gt;
  &lt;TileLayer
    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    attribution="&amp;copy; &lt;a href=&amp;quot;http://osm.org/copyright&amp;quot;&gt;OpenStreetMap&lt;/a&gt; contributors"
  /&gt;
&lt;/Map&gt;
</code></pre>
<p>This gives you a basic map, but we want to swap in Mapbox so we can set up a custom look and feel for our map.</p>
<h3 id="heading-custom-mapbox-tilelayer">Custom Mapbox TileLayer</h3>
<p>To add our custom style, we’ll want to update the <code>url</code> and <code>attribution</code> props of the <code>TileLayer</code> component.</p>
<p>For URL, it will simply be the custom style endpoint we created earlier, so in my example, it looks like:</p>
<pre><code>https:<span class="hljs-comment">//api.mapbox.com/styles/v1/colbyfayock/ck8lryjfq0jdo1ip9ctmuhc6p/tiles/256/{z}/{x}/{y}@2x?access_token=MYACCESSTOKEN</span>
</code></pre><p>For attribution, we want to credit Mapbox as the service, so we want to set our attribution as:</p>
<pre><code><span class="hljs-built_in">Map</span> data &amp;copy; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&amp;quot;https://www.openstreetmap.org/&amp;quot;</span>&gt;</span>OpenStreetMap<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></span> contributors, <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&amp;quot;https://creativecommons.org/licenses/by-sa/2.0/&amp;quot;</span>&gt;</span>CC-BY-SA<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></span>, Imagery &amp;copy; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&amp;quot;https://www.mapbox.com/&amp;quot;</span>&gt;</span>Mapbox<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></span>
</code></pre><p>When plugged in to our <code>TileLayer</code>, our code should now look like this:</p>
<pre><code class="lang-react">&lt;Map center={position} zoom={13}&gt;
  &lt;TileLayer
    url="https://api.mapbox.com/styles/v1/colbyfayock/ck8lryjfq0jdo1ip9ctmuhc6p/tiles/256/{z}/{x}/{y}@2x?access_token=MYACCESSTOKEN"
    attribution="Map data &amp;copy; &lt;a href=&amp;quot;https://www.openstreetmap.org/&amp;quot;&gt;OpenStreetMap&lt;/a&gt; contributors, &lt;a href=&amp;quot;https://creativecommons.org/licenses/by-sa/2.0/&amp;quot;&gt;CC-BY-SA&lt;/a&gt;, Imagery &amp;copy; &lt;a href=&amp;quot;https://www.mapbox.com/&amp;quot;&gt;Mapbox&lt;/a&gt;"
  /&gt;
&lt;/Map&gt;
</code></pre>
<p>And once we open up our map, we should see our new basemap!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/react-leaflet-mapbox-basemap.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>React Leaflet with a Mapbox basemap</em></p>
<h3 id="heading-see-the-code">See the code!</h3>
<p>If you want to see how I did it, <a target="_blank" href="https://github.com/colbyfayock/my-mapbox-react-leaflet/commits/master">check out the diff commit by commit</a>.</p>
<p>The only caveat there is I created an <code>.env.development.local</code> file in the root of my project in which I stored a new environment variable called <code>REACT_APP_MAPBOX_KEY</code>  to store my Mapbox key.</p>
<h2 id="heading-part-3-adding-a-custom-basemap-to-gatsby-starter-leaflet">Part 3: Adding a custom basemap to Gatsby Starter Leaflet</h2>
<p>I’ve written <a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-coronavirus-covid-19-dashboard-map-app-with-gatsby-and-leaflet">a few</a> <a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-summer-road-trip-mapping-app-with-gatsby-and-leaflet">other</a> <a target="_blank" href="https://www.colbyfayock.com/2020/03/anyone-can-map-inspiration-and-an-introduction-to-the-world-of-mapping/">articles</a> on <a target="_blank" href="https://www.freecodecamp.org/news/easily-spin-up-a-mapping-app-in-react-with-leaflet/">how to get started</a> with my <a target="_blank" href="https://github.com/colbyfayock/gatsby-starter-leaflet">Leaflet Gatsby Starter</a>, but for this part, we’ll want to have a basic app spun up that we can use to change our <code>TileLayer</code> endpoint.</p>
<h3 id="heading-setting-up-our-react-leaflet-gatsby-app">Setting up our React Leaflet Gatsby app</h3>
<p>To get started, check out the instructions on the Starter github:</p>
<p><a target="_blank" href="https://github.com/colbyfayock/gatsby-starter-leaflet">https://github.com/colbyfayock/gatsby-starter-leaflet</a></p>
<p>Once you’re ready, you should have a basic mapping app ready to go!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/gatsby-starter-leaflet-in-browser.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New Leaflet Gatsby app in the browser</em></p>
<h3 id="heading-configuring-our-mapbox-service">Configuring our Mapbox service</h3>
<p>The first thing we’ll want to do is add Mapbox as a service in our <code>src/data/map-services.js</code> file.</p>
<p>Taking our custom endpoint URL that we created in Part 1, let’s set up a new object with a name of Mapbox, and with a url and attribution similar to what we did in Part 2.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> mapServices = [
  {
    <span class="hljs-attr">name</span>: ‘OpenStreetMap’,
    <span class="hljs-attr">attribution</span>: <span class="hljs-string">'&amp;copy; &lt;a href="http://osm.org/copyright”&gt;OpenStreetMap&lt;/a&gt; contributors’,
    url: ‘https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png’
  },
  {
    name: ‘Mapbox’,
    attribution: ‘Map data &amp;copy; &lt;a href=&amp;quot;https://www.openstreetmap.org/&amp;quot;&gt;OpenStreetMap&lt;/a&gt; contributors, &lt;a href=&amp;quot;https://creativecommons.org/licenses/by-sa/2.0/&amp;quot;&gt;CC-BY-SA&lt;/a&gt;, Imagery &amp;copy; &lt;a href=&amp;quot;https://www.mapbox.com/&amp;quot;&gt;Mapbox&lt;/a&gt;’,
    url: `https://api.mapbox.com/styles/v1/colbyfayock/ck8c2foj72lqk1jnug0g2haw0/tiles/256/{z}/{x}/{y}@2x?access_token=MY_ACCESS_TOKEN`
  }
];</span>
</code></pre>
<h3 id="heading-using-our-mapbox-map-service">Using our Mapbox map service</h3>
<p>Once you have your Mapbox service set up, all that’s left is to open up the <code>src/pages/index.js</code> file, find the <code>mapSettings</code> object definition, and update the <code>defaultBaseMap</code> property to <code>Mapbox</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> mapSettings = {
  <span class="hljs-attr">center</span>: CENTER,
  <span class="hljs-attr">defaultBaseMap</span>: ‘Mapbox’,
  <span class="hljs-attr">zoom</span>: DEFAULT_ZOOM,
  mapEffect
};
</code></pre>
<p>Save that change, refresh the map in your browser, and you should now see your custom basemap style!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/gatsby-starter-leaflet-with-mapbox-tilelayer-in-browser.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Gatsby Starter Leaflet with custom Mapbox basemap in browser</em></p>
<h3 id="heading-see-the-code-1">See the code!</h3>
<p>If you want to see how I did it, <a target="_blank" href="https://github.com/colbyfayock/my-mapbox-gatsby-starter-leaflet/commit/9baa1b7003504dec5c938328ea9b54477f65ec58">check out the diff with the commit</a>.</p>
<p>The only caveat there is I created an <code>.env.development</code> file in the root of my project in which I stored a new environment variable called <code>GATSBY_MAPBOX_KEY</code>  to store my Mapbox key.</p>
<h2 id="heading-securing-your-mapbox-key">Securing your Mapbox key</h2>
<h3 id="heading-environment-variables">Environment variables</h3>
<p>Part of most development processes that use individual keys will generally set the keys up as environment variables. Environment variables are configured settings that don’t live in the code itself.</p>
<p>This is important because it prevents your key from being checked in to your code, which is bad from a security perspective, but it also allows you to provide a different key for different environments.</p>
<p>When generating your keys, try to keep this in mind, as it can save you in the long run.</p>
<h3 id="heading-locking-down-your-mapbox-key">Locking down your Mapbox key</h3>
<p>In your settings when creating a token or when editing a token, Mapbox allows you to specify only the URLs you want your key to be accessible from.</p>
<p>Though Mapbox has a generous free tier, you probably want to keep it locked down only to the URLs that you’re using it on. You can create multiple keys, where one could be for public use on your website and one would be for your local development.</p>
<p>This is helpful for instance, where you have a key that will never be used publicly for development purposes, but then you have a key that you deploy with, which can be locked down only to that URL.</p>
<p>If someone grabs your key, they could plug it into their own website and use up all of your free tier, potentially running up your bill!</p>
<h2 id="heading-want-to-learn-more-about-maps">Want to learn more about maps?</h2>
<p>You can check out a few of my other resources to get started:</p>
<ul>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-coronavirus-covid-19-dashboard-map-app-with-gatsby-and-leaflet">How to create a Coronavirus (COVID-19) Dashboard &amp; Map App in React with Gatsby and Leaflet</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/anyone-can-map-inspiration-and-an-introduction-to-the-world-of-mapping">Anyone Can Map! Inspiration and an introduction to the world of mapping</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-summer-road-trip-mapping-app-with-gatsby-and-leaflet">How to Create a Summer Road Trip Mapping App with Gatsby and Leaflet</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2019/12/create-your-own-santa-tracker-with-gatsby-and-react-leaflet/">How to Create your own Santa Tracker with Gatsby and React Leaflet</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/easily-spin-up-a-mapping-app-in-react-with-leaflet/">How to build a mapping app in React the easy way with Leaflet</a></li>
</ul>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to create a Coronavirus (COVID-19) Dashboard & Map App in React with Gatsby and Leaflet ]]>
                </title>
                <description>
                    <![CDATA[ The Coronavirus (COVID-19) pandemic has swiftly changed how all of us interact day to day. How can we use available APIs to build a mapping app that shows the impact it has had on the world? Update: The original NovelCOVID API v1 endpoint has been de... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-coronavirus-covid-19-dashboard-map-app-in-react-with-gatsby-and-leaflet/</link>
                <guid isPermaLink="false">66bee92588139a9746c0c5cc</guid>
                
                    <category>
                        <![CDATA[ coronavirus ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Covid-19 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Gatsby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GatsbyJS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leaflet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mapping ]]>
                    </category>
                
                    <category>
                        <![CDATA[ maps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react-leaflet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 31 Mar 2020 15:16:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/coronavirus-mapping-app.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Coronavirus (COVID-19) pandemic has swiftly changed how all of us interact day to day. How can we use available APIs to build a mapping app that shows the impact it has had on the world?</p>
<p><strong>Update:</strong> The original NovelCOVID API v1 endpoint has been deprecated. Please update and use the following instead: <a target="_blank" href="https://corona.lmao.ninja/v2/countries">https://corona.lmao.ninja/v2/countries</a></p>
<p><em>Author’s Note: This is meant to be a demo and proof of concept for putting together an impactful mapping application using real life data. For complete and accurate analysis, please make sure to use tools like <a target="_blank" href="https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6">Johns Hopkins University dashboard</a>. Stay home and be safe! ❤️</em></p>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-what-do-we-need-before-we-get-started">What do we need before we get started?</a></li>
<li><a class="post-section-overview" href="#heading-step-1-cleaning-up-some-unneeded-code">Step 1: Cleaning up some unneeded code</a></li>
<li><a class="post-section-overview" href="#heading-step-2-fetching-the-coronavirus-data">Step 2: Fetching the Coronavirus data</a></li>
<li><a class="post-section-overview" href="#heading-step-3-transform-the-coronavirus-data-into-a-geographic-data-format">Step 3: Transform the Coronavirus data into a geographic data format</a></li>
<li><a class="post-section-overview" href="#heading-step-4-adding-the-coronavirus-data-to-the-map">Step 4: Adding the Coronavirus data to the map</a></li>
<li><a class="post-section-overview" href="#heading-what-else-can-we-do">What else can we do?</a></li>
<li><a class="post-section-overview" href="#heading-be-safe-and-stay-informed">Be safe and stay informed</a></li>
<li><a class="post-section-overview" href="#heading-want-to-learn-more-about-maps">Want to learn more about maps?</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/GryBIsfBfro" 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-are-we-going-to-build">What are we going to build?</h2>
<p>We’ll be putting together a mapping application that uses an API containing recent Coronavirus statistics and maps out the locations and impact each country is facing.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/coronavirus-map-dashboard-demo.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Coronavirus map dashboard demo</em></p>
<p>On the map, we’ll show a marker for each country with the number of confirmed cases. On top of that, we’ll include a little popup tooltip that shows more in depth information.</p>
<p>The map we’ll build will mostly look like the above, but will look a little simpler. We’ll utilize the OpenStreetMap public tileserver instead of using a custom <a target="_blank" href="https://www.mapbox.com/">Mapbox</a></p>
<p>To get started, we’re going to use this <a target="_blank" href="https://github.com/colbyfayock/gatsby-starter-leaflet">Leaflet Gatsby Starter</a> I created to make the initial setup a little smoother. With our app bootstrapped, we’ll fetch our data and add markers to the map with our data.</p>
<h2 id="heading-woah-a-mapping-app">Woah, a mapping app?</h2>
<p>Yup. If you haven’t played with maps before, don’t be discouraged! It's not as bad as you probably think. If you’d rather start with mapping basics, you can <a target="_blank" href="https://www.freecodecamp.org/news/easily-spin-up-a-mapping-app-in-react-with-leaflet/">read more about how mapping works</a> first.</p>
<h2 id="heading-what-do-we-need-before-we-get-started">What do we need before we get started?</h2>
<p>If you followed along with my previous tutorials for <a target="_blank" href="https://www.freecodecamp.org/news/create-your-own-santa-tracker-with-gatsby-and-react-leaflet/">building a Santa Tracker</a> or <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-summer-road-trip-mapping-app-with-gatsby-and-leaflet/">creating a Summer Road Trip map</a>, you can follow the same steps to get started. If not, we’ll want to make sure we have the following set up:</p>
<ul>
<li><a target="_blank" href="https://nodejs.org/en/">node</a> or <a target="_blank" href="https://yarnpkg.com/en/">yarn</a> - I'll be using yarn, but you can substitute with npm where appropriate</li>
<li><a target="_blank" href="https://www.gatsbyjs.org/docs/gatsby-cli/">Gatsby’s CLI</a> - <code>yarn global add gatsby-cli</code></li>
</ul>
<p>If you’re not sure about one of the above, you can try checking out the beginning <a target="_blank" href="https://www.freecodecamp.org/news/create-your-own-santa-tracker-with-gatsby-and-react-leaflet/">my previous tutorial</a>.</p>
<p>We’ll also want to set up a foundation for our map. We can do this by utilizing the Leaflet Gatsby Starter I put together that provides us a basic setup with <a target="_blank" href="https://leafletjs.com/">Leaflet</a> and <a target="_blank" href="https://react-leaflet.js.org/">React Leaflet</a>.</p>
<pre><code class="lang-shell">gatsby new my-coronavirus-map https://github.com/colbyfayock/gatsby-starter-leaflet
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/terminal-creating-new-coronavirus-map-from-gatsby-starter.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a new Leaflet Gatsby app in the terminal</em></p>
<p>After that’s finished running, you can navigate to the newly created project directory and start your local development server:</p>
<pre><code class="lang-shell">cd my-coronavirus-map
yarn develop
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/terminal-starting-gatsby-development-server-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Starting your Gatsby app in the terminal</em></p>
<p>If all goes as planned, your server should start and you should now be able to see your basic mapping app in your browser!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/gatsby-starter-leaflet-in-browser-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New Leaflet Gatsby app in the browser</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commits/master">Follow along with the commit!</a></p>
<h2 id="heading-step-1-cleaning-up-some-unneeded-code">Step 1: Cleaning up some unneeded code</h2>
<p>The Gatsby Starter we're using to spin up this app comes with some demo code that we don’t need here. We’ll want to make all of the changes below in the file <code>src/pages/index.js</code>, which is the homepage of our app.</p>
<p>First, let’s remove everything from the <code>mapEffect</code> function. This function is used to run code that fires when the map renders.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// In src/pages/index.js</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mapEffect</span>(<span class="hljs-params">{ leafletElement } = {}</span>) </span>{
  <span class="hljs-comment">// Get rid of everything in here</span>
}
</code></pre>
<p>We’ll also change the variable name of our <code>leafletElement</code> simply for being able to more easily understand the code as we write it.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mapEffect</span>(<span class="hljs-params">{ leafletElement: map } = {}</span>) </span>{
}
</code></pre>
<p>Next, we don’t want a marker this time, so let’s remove the <code>&lt;Marker</code> component from our <code>&lt;Map</code> component:</p>
<pre><code class="lang-react">&lt;Map {...mapSettings} /&gt;
</code></pre>
<p>Now that we have those pieces cleared out, we can remove all of the following imports and variables from the top of our file:</p>
<ul>
<li>useRef</li>
<li>Marker</li>
<li>promiseToFlyTo</li>
<li>getCurrentLocation</li>
<li>gatsby_astronaut</li>
<li>timeToZoom</li>
<li>timeToOpenPopupAfterZoom</li>
<li>timeToUpdatePopupAfterZoom</li>
<li>ZOOM</li>
<li>popupContentHello</li>
<li>popupContentGatsby</li>
<li>markerRef</li>
</ul>
<p>After, our map should still work, but not do anything.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/new-empty-mapping-app-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New mapping app with nothing going on</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/a3e9cff3949bb7ebb7cc89166c875e97b6dcb5a8">Follow along with the commit!</a></p>
<h2 id="heading-step-2-fetching-the-coronavirus-data">Step 2: Fetching the Coronavirus data</h2>
<p>For our app, we’re going to use the <a target="_blank" href="https://github.com/NovelCOVID/API">NovelCOVID API</a>. Particularly, we’re going to use the <a target="_blank" href="https://corona.lmao.ninja/countries">countries endpoint</a> to fetch the list of our countries and the stats associated with them.</p>
<p>For making requests, I personally like to use <a target="_blank" href="https://github.com/axios/axios">axios</a> as it has a nice to use API. If you want to use <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch</a> or your own favorite request library, substitute that in for this step.</p>
<p>We’ll start by installing axios:</p>
<pre><code class="lang-shell">yarn add axios
</code></pre>
<p>Once that installs, remember to restart your server.</p>
<p>Import the axios package ta the top of our <code>pages/index.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;
</code></pre>
<p>Next we’ll actually make our request. Inside our <code>mapEffect</code> function, let’s try to make a request to the API endpoint:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mapEffect</span>(<span class="hljs-params">{ leafletElement: map } = {}</span>) </span>{
    <span class="hljs-keyword">let</span> response;

    <span class="hljs-keyword">try</span> {
      response = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">'https://corona.lmao.ninja/v2/countries'</span>);
    } <span class="hljs-keyword">catch</span>(e) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Failed to fetch countries: <span class="hljs-subst">${e.message}</span>`</span>, e);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> { data = [] } = response;
}
</code></pre>
<p>In this snippet, we’re doing the following:</p>
<ul>
<li>Setting up a <code>response</code> variable that will allow us to store the response</li>
<li>Adding a <code>try/catch</code> block that will catch any API errors if the request fails</li>
<li>If the request is successful, we store the response in the <code>response</code> variable</li>
<li>If the request fails, we console log out the error and return out of the function so we don’t continue to run the code with a failed request</li>
<li>Once we have our response, we can destructure <code>data</code> from the response and set the default value to an empty array, as that will be the type of data we need</li>
</ul>
<p>After that’s set up, we can console log out the <code>data</code> object and we’ll see our data successfully fetched!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/coronavirus-location-data-in-browser.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Logging the Coronavirus location data to the browser console</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/86bebfee4a34b9bad516879b228921cdaad55126">Follow along with the commit!</a></p>
<p><strong>Update:</strong> The previous commit includes a link to the original NovelCOVID v1 API endpoint which has now been deprecated. Please use this instead: <a target="_blank" href="https://corona.lmao.ninja/v2/countries">https://corona.lmao.ninja/v2/countries</a>.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/e8f63c7ca60ec358b2edc9bc3ed8935be85b5573">See updated commit</a>.</p>
<h2 id="heading-step-3-transform-the-coronavirus-data-into-a-geographic-data-format">Step 3: Transform the Coronavirus data into a geographic data format</h2>
<p>Now that we have our data, we can transform it into a geographic data format, particularly <a target="_blank" href="https://geojson.org/">GeoJSON</a>, that will allow us to interface with Leaflet.</p>
<p>Let’s start by adding this block of code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { data = [] } = response;
<span class="hljs-keyword">const</span> hasData = <span class="hljs-built_in">Array</span>.isArray(data) &amp;&amp; data.length &gt; <span class="hljs-number">0</span>;

<span class="hljs-keyword">if</span> ( !hasData ) <span class="hljs-keyword">return</span>;

<span class="hljs-keyword">const</span> geoJson = {
  <span class="hljs-attr">type</span>: <span class="hljs-string">'FeatureCollection'</span>,
  <span class="hljs-attr">features</span>: data.map(<span class="hljs-function">(<span class="hljs-params">country = {}</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { countryInfo = {} } = country;
    <span class="hljs-keyword">const</span> { lat, <span class="hljs-attr">long</span>: lng } = countryInfo;
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">type</span>: <span class="hljs-string">'Feature'</span>,
      <span class="hljs-attr">properties</span>: {
       ...country,
      },
      <span class="hljs-attr">geometry</span>: {
        <span class="hljs-attr">type</span>: <span class="hljs-string">'Point'</span>,
        <span class="hljs-attr">coordinates</span>: [ lng, lat ]
      }
    }
  })
}
</code></pre>
<p>So what are we doing here?</p>
<ul>
<li>We create a new constant called <code>hasData</code> that checks if our <code>data</code> variable is an array and has data</li>
<li>If we don’t have data, we want to return out of the function, as we don’t want to try to add data we don’t have</li>
<li>We create a <code>geoJson</code> object that will be our GeoJSON document</li>
<li>Our document is of type <code>FeatureCollection</code> and as our <code>features</code> we loop through our dataset</li>
<li>For each country in our data, we obtain the <code>lat</code> and <code>lng</code> to create a point for our map</li>
<li>We additionally add our country data as properties so we can access it within our mapping APIs</li>
</ul>
<p>If you <code>console.log</code> this object our into your browser and copy the contents, you can paste this into geojson.io and see the location data show up correctly.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/location-data-geojson-io.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Previewing Coronavirus location data on geojson.io</em></p>
<p>With this GeoJSON document, we'll now be able to add it to our map.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/f0da2d05cbc16783322684da7a3efaa61022f5b6">Follow along with the commit!</a></p>
<h2 id="heading-step-4-adding-the-coronavirus-data-to-the-map">Step 4: Adding the Coronavirus data to the map</h2>
<p>We have our GeoJSON document with our location data, so let’s add it to the map.</p>
<p>Let’s start with this code block. It's a long one, but we’ll break it down piece by piece:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> geoJsonLayers = <span class="hljs-keyword">new</span> L.GeoJSON(geoJson, {
  <span class="hljs-attr">pointToLayer</span>: <span class="hljs-function">(<span class="hljs-params">feature = {}, latlng</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { properties = {} } = feature;
    <span class="hljs-keyword">let</span> updatedFormatted;
    <span class="hljs-keyword">let</span> casesString;

    <span class="hljs-keyword">const</span> {
      country,
      updated,
      cases,
      deaths,
      recovered
    } = properties

    casesString = <span class="hljs-string">`<span class="hljs-subst">${cases}</span>`</span>;

    <span class="hljs-keyword">if</span> ( cases &gt; <span class="hljs-number">1000</span> ) {
      casesString = <span class="hljs-string">`<span class="hljs-subst">${casesString.slice(<span class="hljs-number">0</span>, <span class="hljs-number">-3</span>)}</span>k+`</span>
    }

    <span class="hljs-keyword">if</span> ( updated ) {
      updatedFormatted = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(updated).toLocaleString();
    }

    <span class="hljs-keyword">const</span> html = <span class="hljs-string">`
      &lt;span class="icon-marker"&gt;
        &lt;span class="icon-marker-tooltip"&gt;
          &lt;h2&gt;<span class="hljs-subst">${country}</span>&lt;/h2&gt;
          &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Confirmed:&lt;/strong&gt; <span class="hljs-subst">${cases}</span>&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Deaths:&lt;/strong&gt; <span class="hljs-subst">${deaths}</span>&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Recovered:&lt;/strong&gt; <span class="hljs-subst">${recovered}</span>&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Last Update:&lt;/strong&gt; <span class="hljs-subst">${updatedFormatted}</span>&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/span&gt;
        <span class="hljs-subst">${ casesString }</span>
      &lt;/span&gt;
    `</span>;

    <span class="hljs-keyword">return</span> L.marker( latlng, {
      <span class="hljs-attr">icon</span>: L.divIcon({
        <span class="hljs-attr">className</span>: <span class="hljs-string">'icon'</span>,
        html
      }),
      <span class="hljs-attr">riseOnHover</span>: <span class="hljs-literal">true</span>
    });
  }
});
</code></pre>
<p>So what are we doing here?</p>
<ul>
<li>We create a new instance of <code>L.GeoJSON</code> which will transform our GeoJSON document into something Leaflet will understand</li>
<li>Inside that instance, we define a custom <code>pointToLayer</code> function. This allows us to customize the map layer Leaflet creates for our map</li>
<li>In our function, we assign and create our datapoints that we want. Most of it is destructuring, but we format the cases count to show <code>1k+</code> instead of <code>1000</code> and a formatted date instead of the timestamp</li>
<li>We create an HTML string block which is used to define our map marker that will be added to the map. This also includes the HTML for the tooltip that will pop up when hovering over a marker</li>
<li>We return <code>L.marker</code> with our custom configuration that includes a class of <code>icon</code> for the container and our custom HTML.</li>
<li>Additionally, we add the <code>riseOnHover</code> property so when hoving over a marker, it surfaces itself above over the other markers on the map</li>
</ul>
<p>We also want to add a bit of CSS here so that we can make sure our markers show up in the map and are usable. Let’s add this snippet to our <code>assets/stylesheets/components/_map.scss</code> file:</p>
<pre><code class="lang-scss"><span class="hljs-selector-class">.icon-marker</span> {

  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">3.6em</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">3.6em</span>;
  <span class="hljs-attribute">font-size</span>: .<span class="hljs-number">7em</span>;
  <span class="hljs-attribute">font-weight</span>: bold;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-variable">$red-800</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">2px</span> <span class="hljs-number">5px</span> rgba(black, .<span class="hljs-number">9</span>);

  &amp;<span class="hljs-selector-pseudo">:hover</span> {

    <span class="hljs-selector-class">.icon-marker-tooltip</span> {
      <span class="hljs-attribute">display</span>: block;
    }

  }

}

<span class="hljs-selector-class">.icon-marker-tooltip</span> {

  <span class="hljs-attribute">display</span>: none;
  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">bottom</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">16em</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.4em</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1em</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-variable">$blue-grey-900</span>;
  <span class="hljs-attribute">border-radius</span>: .<span class="hljs-number">4em</span>;
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">1em</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">3px</span> <span class="hljs-number">5px</span> rgba(black, .<span class="hljs-number">9</span>);

  &amp;<span class="hljs-selector-pseudo">:before</span> {
    <span class="hljs-attribute">display</span>: block;
    <span class="hljs-attribute">position</span>: absolute;
    <span class="hljs-attribute">bottom</span>: -.<span class="hljs-number">6em</span>;
    <span class="hljs-attribute">left</span>: <span class="hljs-number">50%</span>;
    <span class="hljs-attribute">content</span>: <span class="hljs-string">''</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">1.4em</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">1.4em</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-variable">$blue-grey-900</span>;
    <span class="hljs-attribute">transform</span>: rotate(<span class="hljs-number">45deg</span>);
    <span class="hljs-attribute">margin-left</span>: -.<span class="hljs-number">7em</span>;
  }

  <span class="hljs-selector-tag">h2</span> {
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.5em</span>;
    <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.2</span>;
    <span class="hljs-attribute">margin-bottom</span>: .<span class="hljs-number">1em</span>;
    <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0</span>;
  }

  <span class="hljs-selector-tag">h3</span> {
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.2em</span>;
    <span class="hljs-attribute">margin</span>: .<span class="hljs-number">1em</span> <span class="hljs-number">0</span>;
    <span class="hljs-attribute">font-weight</span>: normal;
    <span class="hljs-attribute">color</span>: <span class="hljs-variable">$blue-grey-100</span>;
  }

  <span class="hljs-selector-tag">ul</span>,
  <span class="hljs-selector-tag">p</span> {
    <span class="hljs-attribute">font-weight</span>: normal;
  }

  <span class="hljs-selector-tag">ul</span> {
    <span class="hljs-attribute">list-style</span>: none;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">margin</span>: .<span class="hljs-number">6em</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span>;
  }

}
</code></pre>
<p>What we’re doing:</p>
<ul>
<li>We create our round markers using the <code>.icon-marker</code> class and set up our <code>.icon-marker-tooltip</code> class to show up when hovered over</li>
<li>Our <code>.icon-marker-tooltip</code> class is hidden by default, as it’s our tooltip, but we position it absolutely to appear over top of our marker and formatted the way we want it</li>
</ul>
<p>And finally, once we have our <code>geoJsonLayers</code> created with our styling added, we can add it to the map!</p>
<pre><code>geoJsonLayers.addTo(map)
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2020/03/map-with-coronavirus-location-data.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Map with Coronavirus location data</em></p>
<p>Now you might be wondering why it doesn't appear to be centering properly. Go ahead and change the <code>LOCATION</code> variable at the top of the <code>index.js</code> file to:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> LOCATION = {
  <span class="hljs-attr">lat</span>: <span class="hljs-number">0</span>,
  <span class="hljs-attr">lng</span>: <span class="hljs-number">0</span>
};
</code></pre>
<p>Once that’s set, when the page reloads, the map should be centered in the middle of the world!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/map-with-coronavirus-location-data-centered-tooltip.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Map with Coronavirus location data centered with a tooltip</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-coronavirus-map/commit/49c78e4ef3e98c974fab7bca10b6f8f7578b42c2">Follow along with the commit!</a></p>
<h2 id="heading-yay-we-did-it">Yay, we did it! ?</h2>
<p>If you followed along, you now have created your own Coronavirus map dashboard that gives some quick stats about the cases around the world.</p>
<p>Take what you learned and run with it. You can apply this to any other type of data that you can imagine.</p>
<h2 id="heading-what-else-can-we-do">What else can we do?</h2>
<h3 id="heading-add-more-styles-and-a-custom-basemap">Add more styles and a custom basemap</h3>
<p>In my original demo, I set up a custom basemap using <a target="_blank" href="https://mapbox.com/">Mapbox</a> that allows me to have a dark background making the markers easier to see.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/mapbox-studio-basemap.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a new basemap in Mapbox Studio</em></p>
<p>Mapbox is great and has a nice free tier if you’re interested in getting started.</p>
<p>Once you have a Mapbox account, you can even <a target="_blank" href="https://api.mapbox.com/styles/v1/colbyfayock/ck8c2foj72lqk1jnug0g2haw0.html?fresh=true&amp;title=copy&amp;access_token=pk.eyJ1IjoiY29sYnlmYXlvY2siLCJhIjoiY2swODZzbXYxMGZzdzNjcXczczF6MnlvcCJ9.HCfgUYZUTP7uixjYF7tBSw">copy the style</a> I used and make it your own.</p>
<p><a target="_blank" href="https://api.mapbox.com/styles/v1/colbyfayock/ck8c2foj72lqk1jnug0g2haw0.html?fresh=true&amp;title=copy&amp;access_token=pk.eyJ1IjoiY29sYnlmYXlvY2siLCJhIjoiY2swODZzbXYxMGZzdzNjcXczczF6MnlvcCJ9.HCfgUYZUTP7uixjYF7tBSw">Basic Dark Mapbox Theme</a></p>
<p>To learn how to integrate it, you can try to check out the source code of <a target="_blank" href="https://github.com/colbyfayock/coronavirus-map-dashboard">my original demo</a>:</p>
<p><a target="_blank" href="https://github.com/colbyfayock/coronavirus-map-dashboard">https://github.com/colbyfayock/coronavirus-map-dashboard</a></p>
<h3 id="heading-add-overview-dashboard-stats">Add overview dashboard stats</h3>
<p>Dashboards with maps like the <a target="_blank" href="https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6">Johns Hopkins University app</a> allows us to see more than a look on the map, but a glimpse at quick stats about the cases around the world.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/johns-hopkins-coronavirus-map-march-29.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Johns Hopkins University Coronavirus Map Dashboard - March 29, 2020</em></p>
<p>The <a target="_blank" href="https://github.com/NovelCOVID/API">NovelCOVID API</a> has more endpoints like <code>/all</code> that provide a few global stats.</p>
<h2 id="heading-be-safe-and-stay-informed">Be safe and stay informed</h2>
<p>I want to reiterate that you should make sure you're staying up to date using official sources for information, such as the Johns Hopkins University dashboard. Though the data should be reliable, it should also be considered a proof of concept for building a map and referencing, but shouldn't be considered for any kind of statistical analysis.</p>
<p>Please take care of yourself during these times. We're all in this together! ❤️</p>
<h2 id="heading-want-to-learn-more-about-maps">Want to learn more about maps?</h2>
<p>You can check out a few of my other resources to get started:</p>
<ul>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/anyone-can-map-inspiration-and-an-introduction-to-the-world-of-mapping">Anyone Can Map! Inspiration and an introduction to the world of mapping</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/04/how-to-set-up-a-custom-mapbox-basemap-style-with-react-leaflet-and-leaflet-gatsby-starter/">How to set up a custom Mapbox basemap style with React Leaflet and Leaflet Gatsby Starter</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-summer-road-trip-mapping-app-with-gatsby-and-leaflet">How to Create a Summer Road Trip Mapping App with Gatsby and Leaflet</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2019/12/create-your-own-santa-tracker-with-gatsby-and-react-leaflet/">How to Create your own Santa Tracker with Gatsby and React Leaflet</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/easily-spin-up-a-mapping-app-in-react-with-leaflet/">How to build a mapping app in React the easy way with Leaflet</a></li>
</ul>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Summer Road Trip Mapping App with Gatsby and Leaflet ]]>
                </title>
                <description>
                    <![CDATA[ Get ready for the summer by building your own road trip mapping app with this step-by-step guide! What are we going to build? What do we need before we get started? Step 1: Cleaning up some unneeded code Step 2: Create our road trip locations Step 3... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-summer-road-trip-mapping-app-with-gatsby-and-leaflet/</link>
                <guid isPermaLink="false">66b8e3556a98b2a27ee1f34a</guid>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Gatsby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GatsbyJS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leaflet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mapping ]]>
                    </category>
                
                    <category>
                        <![CDATA[ maps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react-leaflet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Applications ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 24 Mar 2020 13:01:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/road-trip-mapping-app-2.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Get ready for the summer by building your own road trip mapping app with this step-by-step guide!</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-what-do-we-need-before-we-get-started">What do we need before we get started?</a></li>
<li><a class="post-section-overview" href="#id=&quot;step-1-cleaning-up-some-unneeded-code&quot;">Step 1: Cleaning up some unneeded code</a></li>
<li><a class="post-section-overview" href="#heading-step-2-create-our-road-trip-locations">Step 2: Create our road trip locations</a></li>
<li><a class="post-section-overview" href="#heading-step-3-prepare-our-app-with-some-functions">Step 3: Prepare our app with some functions</a></li>
<li><a class="post-section-overview" href="#heading-step-4-building-our-trip-path">Step 4: Building our trip path</a></li>
<li><a class="post-section-overview" href="#heading-step-5-styling-our-map-components">Step 5: Styling our map components</a></li>
<li><a class="post-section-overview" href="#heading-want-to-learn-more-about-maps">Want to learn more about maps?</a></li>
</ul>
<p><em>Author’s Note: Even though we’re going through some challenging times, we can still be optimistic that we’ll get through this together and be able to enjoy our summer. Stay safe and wash your hands. ❤️</em></p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/FkO8uggDEXY" 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-are-we-going-to-build">What are we going to build?</h2>
<p>We’ll be walking through building a new mapping app that shows a route representing the trip. Each location will have a little card where we can add a picture and some things we did.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/summer-road-trip-map.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://summer-road-trip.netlify.com/">Colbana's Summer Road Trip</a></em></p>
<p>To get started, we’re going to use this <a target="_blank" href="https://github.com/colbyfayock/gatsby-starter-leaflet">Leaflet Gatsby Starter</a> I created to make the initial setup a little smoother. With our app bootstrapped, we’ll create our list of locations and use Leaflet’s API to draw our route on the map.</p>
<h2 id="heading-woah-a-mapping-app">Woah, a mapping app?</h2>
<p>Yup. If you haven’t played with maps before, don’t be discouraged! It's not as bad as you probably think. If you’d rather start with mapping basics, you can <a target="_blank" href="https://www.freecodecamp.org/news/easily-spin-up-a-mapping-app-in-react-with-leaflet/">read more about how mapping works</a> first.</p>
<h2 id="heading-what-do-we-need-before-we-get-started">What do we need before we get started?</h2>
<p>If you followed along with my last tutorial for <a target="_blank" href="https://www.freecodecamp.org/news/create-your-own-santa-tracker-with-gatsby-and-react-leaflet/">building a Santa Tracker</a>, you can follow the same steps to get started. If not, we’ll want to make sure we have the following set up:</p>
<ul>
<li><a target="_blank" href="https://nodejs.org/en/">node</a> or <a target="_blank" href="https://yarnpkg.com/en/">yarn</a> - I'll be using yarn, but you can substitute with npm where appropriate</li>
<li><a target="_blank" href="https://www.gatsbyjs.org/docs/gatsby-cli/">Gatsby’s CLI</a> - <code>yarn global add gatsby-cli</code></li>
</ul>
<p>If you’re not sure about one of the above items, you can try checking out the beginning of <a target="_blank" href="https://www.freecodecamp.org/news/create-your-own-santa-tracker-with-gatsby-and-react-leaflet/">my previous tutorial</a>.</p>
<p>We’ll also want to set up a foundation for our map. We can do this by utilizing the Leaflet Gatsby Starter I put together that provides us a basic setup with <a target="_blank" href="https://leafletjs.com/">Leaflet</a> and <a target="_blank" href="https://react-leaflet.js.org/">React Leaflet</a>.</p>
<pre><code class="lang-shell">gatsby new my-road-trip https://github.com/colbyfayock/gatsby-starter-leaflet
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/terminal-creating-new-gatsby-app.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a new Leaflet Gatsby app in the terminal</em></p>
<p>After that’s finished running, you can navigate to the newly created project directory and start your local development server:</p>
<pre><code class="lang-shell">cd my-road-trip
yarn develop
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/terminal-starting-gatsby-development-server.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Starting your Gatsby app in the terminal</em></p>
<p>If all goes as planned, your server should start and you should now be able to see your basic mapping app in your browser!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/gatsby-starter-leaflet-in-browser.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New Leaflet Gatsby app in the browser</em></p>
<h2 id="heading-step-1-cleaning-up-some-unneeded-code">Step 1: Cleaning up some unneeded code</h2>
<p>The Gatsby Starter we're using to spin up this app comes with some demo code that we don’t need here. We’ll want to make all of the changes below in the file <code>src/pages/index.js</code>, which is the homepage of our app.</p>
<p>First, let’s remove everything from the <code>mapEffect</code> function. This function is used to run code that fires when the map renders.</p>
<pre><code class="lang-js"><span class="hljs-comment">// In src/pages/index.js</span>

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mapEffect</span>(<span class="hljs-params">{ leafletElement } = {}</span>) </span>{
  <span class="hljs-comment">// Get rid of everything in here</span>
}
</code></pre>
<p>Next, we don’t want a marker this time, so let’s remove the <code>&lt;Marker</code> component from our <code>&lt;Map</code> component:</p>
<pre><code class="lang-jsx">&lt;<span class="hljs-built_in">Map</span> {…mapSettings} /&gt;
</code></pre>
<p>Now that we have those pieces cleared out, we can remove all of the following imports and variables from the top of our file:</p>
<ul>
<li>useRef</li>
<li>Marker</li>
<li>promiseToFlyTo</li>
<li>getCurrentLocation</li>
<li>gatsby_astronaut</li>
<li>timeToZoom</li>
<li>timeToOpenPopupAfterZoom</li>
<li>timeToUpdatePopupAfterZoom</li>
<li>ZOOM</li>
<li>popupContentHello</li>
<li>popupContentGatsby</li>
<li>markerRef</li>
</ul>
<p>After, our map should still work, but not do anything.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/new-empty-mapping-app.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New mapping app with nothing going on</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-road-trip/commit/c92e8f970c8a2f2436f65ea0890680a88b747c49">Follow along with the commit</a></p>
<h2 id="heading-step-2-create-our-road-trip-locations">Step 2: Create our road trip locations</h2>
<p>This step will involve preparing our location data that will populate our road trip app. Our locations will include properties like a name, date, things we did, and a picture if we want.</p>
<p>First, create a new file in the <code>src/data</code> directory called <code>locations.js</code>.  Inside of that file, we want to create and export a new array.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> locations = [
  {
    <span class="hljs-attr">placename</span>: ‘Herndon, VA’,
    <span class="hljs-attr">date</span>: ‘August <span class="hljs-number">1</span>, <span class="hljs-number">2015</span>’,
    <span class="hljs-attr">location</span>: {
      <span class="hljs-attr">lat</span>: <span class="hljs-number">38.958988</span>,
      <span class="hljs-attr">lng</span>: <span class="hljs-number">-77.417320</span>
    },
    <span class="hljs-attr">todo</span>: [
      ‘Where we start! ?’
    ]
  },
  {
    <span class="hljs-attr">placename</span>: ‘Middlesboro, KY<span class="hljs-string">',
    date: ‘August 1, 2015’,
    location: {
      lat: 36.627517,
      lng: -83.621635
    },
    todo: [
      ‘Cumberland Gap ?’
    ]
  }
];</span>
</code></pre>
<p>You can use the above to get started, but you’ll eventually want to change the details to something of your choosing.</p>
<p>If you want to add an image to your location, you can do so by including an <code>image</code> property to the object. You can use either a URL string or you can import a local file if you have one available, like I’m doing in this example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> imgHerndonStart <span class="hljs-keyword">from</span> <span class="hljs-string">'assets/images/herndon-start.jpg’;

export const locations = [
  {
    placename: ‘Herndon, VA’,
    date: ‘August 1, 2015’,
    image: imgHerndonStart,
    location: {
      lat: 38.958988,
      lng: -77.417320
    },
    todo: [
      ‘Where we start! ?’
    ]
  }
]</span>
</code></pre>
<p>Once we have that file created, we can now import our locations into our <code>src/pages/index.js</code> file so we can use it in our next step:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { locations } <span class="hljs-keyword">from</span> <span class="hljs-string">'data/locations’;</span>
</code></pre>
<p>If you add a <code>console.log(locations)</code> inside of your page, you should now see all of your location data in an array!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-road-trip/commit/55f4eb32d402364a20ad0342ebfde995081c521e">Follow along with the commit</a></p>
<h2 id="heading-step-3-prepare-our-app-with-some-functions">Step 3: Prepare our app with some functions</h2>
<p>To try to keep things simple and focused, I grouped together 3 important components of creating our map into functions. Though it’s available to copy and paste, we’ll walk through what’s happening in each function.</p>
<p>You can place each of these functions at the bottom of the <code>src/pages/index.js</code> file so they’re ready to use in our next step.</p>
<h3 id="heading-createtrippointsgeojson">createTripPointsGeoJson</h3>
<p>Our first function is going to take the array of our locations and return a <a target="_blank" href="https://geojson.org/">GeoJSON document</a>, with our locations mapped into an individual Feature. We’ll use this function to create the individual points on our map.</p>
<p>What is a GeoJSON document? It's essentially a JavaScript object or JSON document with a specific structure that creates consistency with geographical data.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createTripPointsGeoJson</span>(<span class="hljs-params">{ locations } = {}</span>) </span>{
  <span class="hljs-keyword">return</span> {
    “type”: “FeatureCollection”,
    “features”: locations.map(<span class="hljs-function">(<span class="hljs-params">{ placename, location = {}, image, date, todo = [] } = {}</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> { lat, lng } = location;
      <span class="hljs-keyword">return</span> {
        “type”: “Feature”,
        “properties”: {
          placename,
          todo,
          date,
          image
        },
        “geometry”: {
          “type”: “Point”,
          “coordinates”: [ lng, lat ]
        }
      }
    })
  }
}
</code></pre>
<p>So what’s happening in the above?</p>
<ul>
<li>We take an argument of locations, which will be our array of destinations</li>
<li>We return an object with some dynamic properties associated with it</li>
<li>Within the object, we map our locations to individual <code>Feature</code> objects</li>
<li>Each object includes a <code>Point</code> shape using our coordinates</li>
<li>It additionally includes our properties that store our metadata</li>
</ul>
<p>When this function is invoked, we will have a newly created JavaScript object that includes an array of Points representing the locations we are stopping at on our road trip.</p>
<h3 id="heading-createtriplinesgeojson">createTripLinesGeoJson</h3>
<p>We’re going to create another function that’s similar to the previous one. This time however, instead of points, we want to create lines that represent going from one point to the next.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createTripLinesGeoJson</span>(<span class="hljs-params">{ locations } = {}</span>) </span>{
  <span class="hljs-keyword">return</span> {
    “type”: “FeatureCollection”,
    “features”: locations.map(<span class="hljs-function">(<span class="hljs-params">stop = {}, index</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> prevStop = locations[index - <span class="hljs-number">1</span>];

      <span class="hljs-keyword">if</span> ( !prevStop ) <span class="hljs-keyword">return</span> [];

      <span class="hljs-keyword">const</span> { placename, location = {}, date, todo = [] } = stop;
      <span class="hljs-keyword">const</span> { lat, lng } = location;
      <span class="hljs-keyword">const</span> properties = {
        placename,
        todo,
        date
      };

      <span class="hljs-keyword">const</span> { <span class="hljs-attr">location</span>: prevLocation = {} } = prevStop;
      <span class="hljs-keyword">const</span> { <span class="hljs-attr">lat</span>: prevLat, <span class="hljs-attr">lng</span>: prevLng } = prevLocation;

      <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">type</span>: ‘Feature’,
        properties,
        <span class="hljs-attr">geometry</span>: {
          <span class="hljs-attr">type</span>: ‘LineString’,
          <span class="hljs-attr">coordinates</span>: [
            [ prevLng, prevLat ],
            [ lng, lat ]
          ]
        }
      }
    })
  }
}
</code></pre>
<p>So you’ll immediately notice that this is very similar to our last function. We’re returning an object and setting our metadata properties on a list of Features.</p>
<p>The big difference, however, is that we're creating a Line. To do this, we're looking up and referring to <code>prevStop</code> which will be the previous stop. We’ll use both the previous stop and our current stop in order to have 2 points which we can use to draw the line. </p>
<p>If we don’t have a previous stop, we return an empty array, which basically means we’re at the beginning of our journey with no line before it.</p>
<p>With the previous stop and current stop, we create a <code>LineString</code> type of Feature with our 2 points.</p>
<h3 id="heading-tripstoppointtolayer">tripStopPointToLayer</h3>
<p>Our last function is going to allow us to create custom content for each of the points that we will be adding to our map. We’ll actually be utilizing this function within a Leaflet property, so we’ll be conforming our arguments to that specification.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tripStopPointToLayer</span>(<span class="hljs-params"> feature = {}, latlng </span>) </span>{
  <span class="hljs-keyword">const</span> { properties = {} } = feature;
  <span class="hljs-keyword">const</span> { placename, todo = [], image, date } = properties;

  <span class="hljs-keyword">const</span> list = todo.map(<span class="hljs-function"><span class="hljs-params">what</span> =&gt;</span> <span class="hljs-string">`&lt;li&gt;<span class="hljs-subst">${ what }</span>&lt;/li&gt;`</span>);
  <span class="hljs-keyword">let</span> listString = ‘’;
  <span class="hljs-keyword">let</span> imageString = ‘’;

  <span class="hljs-keyword">if</span> ( <span class="hljs-built_in">Array</span>.isArray(list) &amp;&amp; list.length &gt; <span class="hljs-number">0</span> ) {
    listString = list.join(‘’);
    listString = <span class="hljs-string">`
      &lt;p&gt;Things we will or have done…&lt;/p&gt;
      &lt;ul&gt;<span class="hljs-subst">${listString}</span>&lt;/ul&gt;
    `</span>
  }

  <span class="hljs-keyword">if</span> ( image ) {
    imageString = <span class="hljs-string">`
      &lt;span class=“trip-stop-image” style=“background-image: url(<span class="hljs-subst">${image}</span>)”&gt;<span class="hljs-subst">${placename}</span>&lt;/span&gt;
    `</span>;
  }

  <span class="hljs-keyword">const</span> text = <span class="hljs-string">`
    &lt;div class=“trip-stop”&gt;
      <span class="hljs-subst">${ imageString }</span>
      &lt;div class=“trip-stop-content”&gt;
        &lt;h2&gt;<span class="hljs-subst">${placename}</span>&lt;/h2&gt;
        &lt;p class=“trip-stop-date”&gt;<span class="hljs-subst">${date}</span>&lt;/p&gt;
        <span class="hljs-subst">${ listString }</span>
      &lt;/div&gt;
    &lt;/div&gt;
  `</span>;

  <span class="hljs-keyword">const</span> popup = L.popup({
    <span class="hljs-attr">maxWidth</span>: <span class="hljs-number">400</span>
  }).setContent(text);

  <span class="hljs-keyword">const</span> layer = L.marker( latlng, {
    <span class="hljs-attr">icon</span>: L.divIcon({
      <span class="hljs-attr">className</span>: ‘icon’,
      <span class="hljs-attr">html</span>: <span class="hljs-string">`&lt;span class=“icon-trip-stop”&gt;&lt;/span&gt;`</span>,
      <span class="hljs-attr">iconSize</span>: <span class="hljs-number">20</span>
    }),
    <span class="hljs-attr">riseOnHover</span>: <span class="hljs-literal">true</span>
  }).bindPopup(popup);

  <span class="hljs-keyword">return</span> layer;
}
</code></pre>
<p>One thing you’ll notice as we work through this function is that we create strings of HTML text. Given that the Leaflet API we’re utilizing for this doesn’t interface directly with React, we have to build out HTML manually to pass it in to our functions.</p>
<p>Starting from the top:</p>
<ul>
<li>We take in 2 arguments, <code>feature</code> and <code>latlng</code>. Leaflet passes these 2 values in for us to use in our function.</li>
<li>We destructure our feature, allowing us to assign our metadata into variables</li>
<li>2 string variables are initialized that we’ll use for our HTML</li>
<li>If we include a <code>todo</code> property as an array, we add a new list with each item inside.</li>
<li>If we include an image, we create an image tag.</li>
<li>With our newly created HTML strings, we construct the entirety of what will be our popup card for each strop</li>
<li>With our popup HTML, we create a Leaflet <code>popup</code> instance</li>
<li>With the latlng argument and our popup, we create a new Leaflet <code>marker</code>  instance. This will represent the point on the map.</li>
<li>Inside of the Marker creation, we create a basic HTML tag that well use to style the marker</li>
<li>We then bind our popup to this new Marker instance. This will allow the popup to be associated with that individual Marker</li>
<li>Finally, we return our newly created layer</li>
</ul>
<p>Remember to make sure you put all of the functions above at the bottom of your <code>src/pages/index.js</code> page.</p>
<p>Once all of those functions are added, our map should still be the same thing, basically nothing happening.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-road-trip/commit/b27b644b32a11e4372963b9d16e0f7ec0ee74b65">Follow along with the commit</a></p>
<h2 id="heading-step-4-building-our-trip-path">Step 4: Building our trip path</h2>
<p>This is where things get interesting. We’ll now utilize the functions we created to build our road trip path. All of our work here will be within the <code>mapEffect</code> function inside of the <code>src/pages/index.js</code> file.</p>
<p>For context, our <code>mapEffect</code> function includes an argument called <code>leafletElement</code>. This value refers to the Map instance that Leaflet recognizes. This Map instance includes our map state as well as many utility functions to work with our map.</p>
<p>First, at the top of the function, we want to make sure we have a map. If not, we can return to bail out of the function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">if</span> ( !leafletElement ) <span class="hljs-keyword">return</span>;
</code></pre>
<p>Next, we want to use the <code>eachLayer</code> utility function and remove each <code>layer</code> from our map element. We do this to make sure we always have the correct map layer state.</p>
<pre><code class="lang-js">leafletElement.eachLayer(<span class="hljs-function">(<span class="hljs-params">layer</span>) =&gt;</span> leafletElement.removeLayer(layer));
</code></pre>
<p>With our cleaned up map, we can utilize 2 of the functions we created to create new GeoJSON objects.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> tripPoints = createTripPointsGeoJson({ locations });
<span class="hljs-keyword">const</span> tripLines = createTripLinesGeoJson({ locations });
</code></pre>
<p>With our GeoJSON objects, we need to convert those to Leaflet GeoJSON instances, which we’ll use to add to the map.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> tripPointsGeoJsonLayers = <span class="hljs-keyword">new</span> L.geoJson(tripPoints, {
  <span class="hljs-attr">pointToLayer</span>: tripStopPointToLayer
});

<span class="hljs-keyword">const</span> tripLinesGeoJsonLayers = <span class="hljs-keyword">new</span> L.geoJson(tripLines);
</code></pre>
<p>If you notice in the above, we're using our <code>tripStopPointToLayer</code> function. As I alluded to before, the <code>geoJson</code> instance we’re creating includes a property that allows us to pass in a function, giving us the ability to manipulate the layer creation. This is how we create our point and popup content.</p>
<p>We can proceed to adding both of those new layers to our map using the <code>addTo</code> .</p>
<pre><code class="lang-js">tripPointsGeoJsonLayers.addTo(leafletElement);
tripLinesGeoJsonLayers.addTo(leafletElement);
</code></pre>
<p>Next, to make sure we zoom and center on the right location, we want to grab the bounds of the map using the <code>getBounds</code> function on our GeoJSON layer instance.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bounds = tripPointsGeoJsonLayers.getBounds();
</code></pre>
<p>Finally, we fit our map's view to those bounds using the <code>fitBounds</code> function on our Map instance.</p>
<pre><code class="lang-js">leafletElement.fitBounds(bounds);
</code></pre>
<p>Once you save  and reload the page, you should now see a blue path representing the jump from each of our locations on the map!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/mapping-app-with-road-trip-path.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Mapping app with road trip path</em></p>
<p>One issue though. If you notice, we only see the path. This is because we need to add some CSS which we’ll get to in the next step.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-road-trip/commit/6b3f079bebdd60bf012c0886fc33547c98ea50f5">Follow along with the commit</a></p>
<h2 id="heading-step-5-styling-our-map-components">Step 5: Styling our map components</h2>
<p>Our last step will be adding some styles that will allow our markers to show and our popups to look just right.</p>
<p>In this step, we’ll be working inside of the <code>_home.scss</code> file, which you can find in <code>src/assets/stylesheets/pages</code>.</p>
<p>We can get started by copy and pasting this block of styles into the bottom of that file. With that done, we can walk through what’s happening.</p>
<pre><code class="lang-scss"><span class="hljs-selector-class">.trip-stop</span> {

  <span class="hljs-attribute">width</span>: <span class="hljs-number">400px</span>;
  <span class="hljs-attribute">overflow</span>: hidden;

  <span class="hljs-selector-tag">h2</span> {
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.4em</span>;
    <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">margin-bottom</span>: .<span class="hljs-number">2em</span>;
  }

  <span class="hljs-selector-tag">p</span>,
  <span class="hljs-selector-tag">ul</span>,
  <span class="hljs-selector-tag">h3</span> {
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.2em</span>;
    <span class="hljs-attribute">font-weight</span>: normal;
  }

  <span class="hljs-selector-tag">p</span> {
    <span class="hljs-attribute">margin</span>: .<span class="hljs-number">2em</span> <span class="hljs-number">0</span>;
  }

  <span class="hljs-selector-class">.trip-stop-date</span> {
    <span class="hljs-attribute">color</span>: <span class="hljs-variable">$grey-600</span>;
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1em</span>;
  }

  <span class="hljs-selector-tag">ul</span> {
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">1.4em</span>;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  }

}

<span class="hljs-selector-class">.trip-stop-image</span> {
  <span class="hljs-attribute">display</span>: block;
  <span class="hljs-attribute">float</span>: left;
  <span class="hljs-attribute">overflow</span>: hidden;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">150px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">150px</span>;
  <span class="hljs-attribute">text-indent</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">color</span>: transparent;
  <span class="hljs-attribute">background-position</span>: center;
  <span class="hljs-attribute">background-size</span>: cover;
}

<span class="hljs-selector-class">.trip-stop-content</span> {
  <span class="hljs-attribute">float</span>: left;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">250px</span>;
  <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">1em</span>;
}

<span class="hljs-selector-class">.icon-trip-stop</span> {

  <span class="hljs-attribute">display</span>: block;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">1.5em</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">1.5em</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-variable">$orange-500</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">2px</span> <span class="hljs-number">5px</span> rgba(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,.<span class="hljs-number">5</span>);

  &amp;<span class="hljs-selector-pseudo">:hover</span> {
    <span class="hljs-attribute">background-color</span>: <span class="hljs-variable">$deep-orange-400</span>;
  }

}
</code></pre>
<p>There’s three components to our styles above:</p>
<ul>
<li><code>.trip-stop-images</code>: Inside of the marker popup, we optionally can include an image. These styles set the size, make the text transparent, (it’s there for accessibility), and float it to the left so that our popup content can align correctly side by side.</li>
<li><code>.trip-stop-content</code>: This refers to the other half of our popup content. All we need to do here is make sure our size is appropriate and that it floats next to our image.</li>
<li><code>.icon-trip-stop</code>: The HTML tag that we’re using as our icon designation gets styled here. We size it up, set a color using a predetermined Scss variable, and we’re good to go.</li>
</ul>
<p>Once those styles are saved, you should now see the points on the map representing each location. Additionally, you should be able to click each of these points to open up a popup containing information about the stop.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/road-trip-mapping-app-with-popup.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Road trip mapping app with popups</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-road-trip/commit/d2bac5c1b04a32837366de6f15f14d5342134d38">Follow along with the commit</a></p>
<h2 id="heading-optional-last-step-style-tweaks">Optional Last Step: Style Tweaks</h2>
<p>The last thing that's completely optional is to make a few style tweaks to give your site a little personality. I’m not going to go over this in details, but if you’d like to follow along and dress things up a little bit, you can follow along with <a target="_blank" href="https://github.com/colbyfayock/my-road-trip/commit/c2c667da6e34595bc6d8dd0ee66e55d4155feed2">this commit</a> which shows each code change I made.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/road-trip-mapping-app.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Final version of the road trip mapping app</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-road-trip/commit/c2c667da6e34595bc6d8dd0ee66e55d4155feed2">Follow along with the commit</a></p>
<h2 id="heading-yay-we-did-it">Yay, we did it!</h2>
<p>If you followed along with me, or skipped right to the starter, you should now have a mapping app that you can use for your next road trip.</p>
<p>The good news is this project can apply to anything! Want to map out your favorite restaurants in Washington, DC? Add your locations and remove the lines. Want to create line drawings over the map? That's certainly an option.</p>
<p>Whatever it is, if you enjoyed getting this map spun up, get creative and apply it to your next project!</p>
<h2 id="heading-want-to-learn-more-about-maps">Want to learn more about maps?</h2>
<p>You can check out a few of my other resources to get started:</p>
<ul>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/how-to-create-a-coronavirus-covid-19-dashboard-map-app-with-gatsby-and-leaflet">How to create a Coronavirus (COVID-19) Dashboard &amp; Map App in React with Gatsby and Leaflet</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/04/how-to-set-up-a-custom-mapbox-basemap-style-with-react-leaflet-and-leaflet-gatsby-starter/">How to set up a custom Mapbox basemap style with React Leaflet and Leaflet Gatsby Starter</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/03/anyone-can-map-inspiration-and-an-introduction-to-the-world-of-mapping">Anyone Can Map! Inspiration and an introduction to the world of mapping</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2019/12/create-your-own-santa-tracker-with-gatsby-and-react-leaflet/">How to Create your own Santa Tracker with Gatsby and React Leaflet</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/easily-spin-up-a-mapping-app-in-react-with-leaflet/">How to build a mapping app in React the easy way with Leaflet</a></li>
</ul>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to instantly make your front end projects look better ]]>
                </title>
                <description>
                    <![CDATA[ By Peter Gleeson We’ve all been there. You’ve been learning the basics of front end Web development, and you are keen to try out some new ideas. You take the time to code up the perfect HTML page, and add some styles and JavaScript for good measure. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-your-front-end-projects/</link>
                <guid isPermaLink="false">66d460a3ffe6b1f641b5fa61</guid>
                
                    <category>
                        <![CDATA[ Bootstrap ]]>
                    </category>
                
                    <category>
                        <![CDATA[ colors ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 09 Mar 2020 11:07:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9c3f740569d1a4ca30eb.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Peter Gleeson</p>
<p>We’ve all been there. You’ve been learning the basics of front end Web development, and you are keen to try out some new ideas.</p>
<p>You take the time to code up the perfect HTML page, and add some styles and JavaScript for good measure.</p>
<p>Then you pause. Time to take a moment to step back and see how your efforts look in the browser.</p>
<p>Pretty terrible, right?</p>
<p>That was certainly my experience when I first learned a little front end development.</p>
<p>I’d put a lot of thought into the functionality of the site. But when I put everything together, it looked awful.</p>
<p>I wanted to share my work with a few friends to get feedback. But in its present state, my site wasn’t ready.</p>
<p>You see, functionality is only half the story. We humans for whatever reason are biased towards the appearance or presentation of something.</p>
<p>Perhaps we’re more likely to trust a site that appears professional and well-designed. Or maybe the aesthetic value of a well-designed site can help us overlook minor flaws in functionality.</p>
<p>Whatever the reason, something of a “<a target="_blank" href="https://en.wikipedia.org/wiki/Halo_effect">halo effect</a>” does exist in Web development.</p>
<p>In this article, you’ll learn a few easy tips to make your ugly af front end project look better in no time.</p>
<h3 id="heading-the-starting-point">The starting point</h3>
<p>Below is an example of a simple HTML page with no styling at all.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/pg2020/embed/PoqOQmG" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>This will be the starting point for the rest of the article. Each tip will build on top of the earlier ones until you have a better looking page to work with.</p>
<p>We’ll go in order of impact. That is, we’ll start with the tip that gives you the quickest improvement and make smaller and smaller gains as we go.</p>
<h3 id="heading-add-some-negative-space">Add some negative space</h3>
<p>The first tip is easy to picture, but needs to be put into practice carefully.</p>
<p>‘Negative space' refers to the empty space between elements on the page.</p>
<p>Getting the right amount of negative space goes a long way to making your page look better.</p>
<p>Specifically, it does two things:</p>
<ul>
<li>It makes the page less cluttered. It is easier to find the different elements, because the negative space helps them stand out from each other.</li>
<li>It makes better use of the available screen space. Spacing the elements out carefully can help fill parts of the screen that are more central, and reduce content in parts on the edges.</li>
</ul>
<p>Check the CSS in the example below. This adds some basic negative space to the simple example you saw earlier.</p>
<p>And here is the result:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/pg2020/embed/oNXoEWK" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>Notice what has happened here:</p>
<ul>
<li>Padding creates space within an element</li>
<li>Margin creates space between the elements</li>
<li>Line-size makes text less cluttered</li>
</ul>
<p>Too much empty space isn’t a good look. It can be tricky to get the balance right.</p>
<h3 id="heading-pair-your-fonts">Pair your fonts</h3>
<p>The next tip is another one with a quick impact.</p>
<p>The default system fonts are very safe and sensible. They are guaranteed to work.</p>
<p>But the choice of font makes a huge statement about the purpose and feel of your site.</p>
<ul>
<li>Light, playful fonts tell the viewer this page is fun and accessible</li>
<li>Sensible, simple fonts give a more business-like appearance</li>
<li>Traditional or display fonts give more of a timeless, classic look.</li>
</ul>
<p>You get the idea.</p>
<p>But how to put it into practice?</p>
<p>The key is to use font pairs.</p>
<p>The idea is that using two fonts for different elements on the page provides a helpful contrast. Again, this helps make elements stand out and makes your page easier to view.</p>
<p>But you shouldn’t pair up any old fonts.</p>
<p>For <a target="_blank" href="https://www.canva.com/learn/combining-fonts-10-must-know-tips-from-a-designer/">a bunch of aesthetic reasons</a>, some font pairings look much better than others.</p>
<p>Don’t worry about figuring this out yourself, though. As usual, there are resources on the Internet to help you.</p>
<p>Check out <a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-your-front-end-projects/fontpair.co">fontpair.co</a>. It lets you browse different font pairings and see how they look together.</p>
<p>Once you find a pairing you like, the quickest way to use them in your project is to head over to <a target="_blank" href="https://fonts.google.com/">Google Fonts</a>.</p>
<ul>
<li>Search for the fonts you want</li>
<li>Add them to your project</li>
<li>Include the link in your HTML <code>&lt;head&gt;</code> element</li>
<li>Reference the fonts in the stylesheet</li>
</ul>
<p>See below for an example built on top of the basic page you saw earlier.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/pg2020/embed/ZEGaraM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>You can also improve the appearance by controlling the font size and text alignment.</p>
<p>Doesn’t that look considerably better? And after only two easy steps.</p>
<h3 id="heading-get-a-colour-scheme">Get a colour scheme</h3>
<p>I’m no designer, but I appreciate the value of learning <a target="_blank" href="https://lifehacker.com/learn-the-basics-of-color-theory-to-know-what-looks-goo-1608972072">the basics of colour theory</a>.</p>
<p>In short, the colours you use on your page go a long way to creating an impression.</p>
<p>For example:</p>
<ul>
<li>Bright, exuberant colours create an energetic feel</li>
<li>Light, toned down shades create a more corporate impression</li>
<li>Dark, contrasting colours create a more dramatic impression</li>
<li>Brand colours create a consistent identity</li>
</ul>
<p>Again, it pays to choose your colours carefully.</p>
<p>The theory goes that the relationship between the colours you use also impacts the appearance of your site.</p>
<ul>
<li>Analogous colours can create a consistent, harmonious appearance</li>
<li>Complementary colours create a pleasing contrast</li>
<li>Triadic colours provide both contrast and balance</li>
</ul>
<p>It pays to pick a colour scheme carefully.</p>
<p>Luckily, there are many ways to do this. Just Google "colour scheme generator" and you will be spoiled for choice.</p>
<p>One of my favourite tools is <a target="_blank" href="http://colormind.io/template/paper-dashboard/">colormind.io</a>. It generates a colour scheme and lets you preview it on a template.</p>
<p>Of course, rules can be broken. Using a more discordant colour scheme can be jarring, but used carefully can give a page an edgier, more stand-out appearance.</p>
<p>See the code below has been updated to use a simple colour scheme.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/pg2020/embed/MWwOQXq" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<h3 id="heading-add-some-structure">Add some structure</h3>
<p>No matter how well-presented your page is right now, it can be improved by shaking things up a bit.</p>
<p>Adding in sections and structure can break up the monotony of a longer page.</p>
<p>By creating clear bounds between elements, you can create a logical structure and/or hierarchy. This will make it easier for the viewer to understand your page layout.</p>
<p>Keep to the same colour scheme, but vary things up a little.</p>
<p>See the example below has been extended to include more of a structure. The content is divided into <code>&lt;header&gt;</code>, <code>&lt;footer&gt;</code> and <code>&lt;div class="content"&gt;</code> elements.</p>
<p>The example also uses a media query to make the page present better on smaller devices.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/pg2020/embed/zYGPRVg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>If you want to learn more, try looking into:</p>
<ul>
<li><a target="_blank" href="https://css-tricks.com/snippets/css/complete-guide-grid/">CSS Grid</a> for creating a layout</li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox">Flexbox</a> for creating layouts</li>
<li><a target="_blank" href="https://getbootstrap.com/docs/3.4/css/">Bootstrap</a> for creating responsive designs</li>
<li>Responsive design with <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Media_queries">media queries</a></li>
</ul>
<p>It didn’t take much rewriting, but the effect is very noticeable.</p>
<h3 id="heading-add-some-images-and-icons">Add some images and icons</h3>
<p>Humans are typically visual creatures. A well placed image or icon can go a long way to making a page easier to view and understand.</p>
<p>The code below adds a simple image to the main content. See how it is included in the <code>&lt;div class="content"&gt;</code> element and the width is set to 100%? This keeps the structure of the page consistent.</p>
<p>Remember, images should be considered in the context of the overall colour scheme.</p>
<p>You don’t need to be a budding CSS artist or Photoshop wizard to do this. If you need access to high quality photos quickly, your can search <a target="_blank" href="https://unsplash.com/">Unsplash</a> for free-to-use images.</p>
<p>Even a few free icons can make a difference.</p>
<p>The example below adds a simple menu icon to the top right corner. You could also add icons to your Github profile, or other online profiles.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/pg2020/embed/zYGPWrY" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>You can quickly add free icons from these resources:</p>
<ul>
<li><a target="_blank" href="https://fontawesome.com/">Fontawesome</a></li>
<li><a target="_blank" href="https://icons.getbootstrap.com/">Bootstrap</a></li>
<li><a target="_blank" href="https://material.io/resources/icons/?style=baseline">Google</a></li>
<li><a target="_blank" href="https://www.keycdn.com/blog/icon-library">Plenty of others</a></li>
</ul>
<h3 id="heading-add-some-animations">Add some animations</h3>
<p>This final tip is a nice-to-have for sure.</p>
<p>As anyone who used PowerPoint during the 2000s will know, animations need to be used carefully.</p>
<p>Too many animations can be confusing and irritating for users.</p>
<p>But used properly, they can make a page much more interactive and visually appealing.</p>
<p>There are lots of ways to add animations to your site. You can use <a target="_blank" href="https://www.w3schools.com/cssref/sel_hover.asp">CSS selectors</a> to change style in response to certain events, such as when the user hovers on that element.</p>
<p>The example below changes the image opacity to 50% when the user hovers over it.</p>
<p>Another option is to use is <a target="_blank" href="https://daneden.github.io/animate.css/">Animate.css</a>. This provides a number of pre-built animations that you can use straight out-of-the-box.</p>
<p>The code below adds a subtle animation to the buttons when it is clicked.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/pg2020/embed/xxGPWEZ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>Remember — with animation, less is usually more!</p>
<h4 id="heading-the-final-result">The final result</h4>
<p>See <a target="_blank" href="https://github.com/pg0408/frontend-demo">this Github repo</a> for overall evolution of the page.</p>
<p>The design still has a long way to go. But just by following some simple guidelines, it looks much better than it did at the start.</p>
<p>Here’s a quick review of each of the tips:</p>
<ol>
<li>Add some negative space</li>
<li>Choose a pair of fonts</li>
<li>Pick a coherent colour scheme</li>
<li>Add some structure</li>
<li>Add a few icons or images</li>
<li>(Optionally) add some animation</li>
</ol>
<p>Leave a response below if you found this quick guide helpful. Do you have any tips or tricks you want to share?</p>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
