<?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[ content delivery network  - 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[ content delivery network  - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 05 Jun 2026 20:27:45 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/content-delivery-network/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Caching vs Content Delivery Networks – What's the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ By Anamika Ahmed In the world of network optimization, Content Delivery Networks (CDNs) and caching play a vital role in improving website performance and user experience.  And while both aim to speed up website loading times, they have distinct purp... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/caching-vs-content-delivery-network/</link>
                <guid isPermaLink="false">66d45d99680e33282da25e0c</guid>
                
                    <category>
                        <![CDATA[ caching ]]>
                    </category>
                
                    <category>
                        <![CDATA[ content delivery network  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 01 Mar 2024 19:27:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/Conducting-Research-Projects-Educational-Presentation-in-Pink-and-Yellow-Colorful-Line-Style-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Anamika Ahmed</p>
<p>In the world of network optimization, Content Delivery Networks (CDNs) and caching play a vital role in improving website performance and user experience. </p>
<p>And while both aim to speed up website loading times, they have distinct purposes and mechanisms. </p>
<p>In this tutorial, we'll dive deep into the details of CDNs and caching to understand their similarities, differences, and how they contribute to enhancing online experiences.</p>
<h3 id="heading-heres-what-well-cover">Here's what we'll cover:</h3>
<ol>
<li><a class="post-section-overview" href="#heading-what-is-caching">What is Caching?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-content-delivery-network-cdn">What is a Content Delivery Network (CDN)?</a></li>
<li><a class="post-section-overview" href="#heading-caching-vs-cdns-whats-the-difference">Caching vs CDNs – What's the Difference?</a></li>
<li><a class="post-section-overview" href="#heading-when-to-use-caching">When to Use Caching</a></li>
<li><a class="post-section-overview" href="#heading-when-to-use-cdns">When to use CDNs</a></li>
<li><a class="post-section-overview" href="#heading-combining-caching-and-cdns">Combining Caching and CDNs</a></li>
<li><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></li>
</ol>
<h2 id="heading-what-is-caching">What is Caching?</h2>
<p>Imagine you’re a librarian managing a popular library. Every day, readers come in asking for the same set of books like “Think and Grow Rich” or “The Intelligent Investor.” </p>
<p>Initially, you fetch these books from the main shelves, which takes time and effort. But soon, you notice a pattern: the same set of books are requested repeatedly by different readers. So, what do you do?</p>
<p>You decide to create a special section near the entrance where you keep copies of these frequently requested books. Now, when readers come asking for them, you don’t have to run to the main shelves each time. Instead, you simply hand them the copies from the special section, saving time and making the process more efficient. </p>
<p>This special section represents the cache, storing frequently accessed books for quick retrieval.</p>
<p>Caching is a technique used to store copies of frequently accessed data temporarily. The cached data can be anything from web pages and images to database query results. When a user requests cached content, the server retrieves it from the cache instead of generating it anew, significantly reducing response times.</p>
<p>When a web server receives a request, it can follow different caching strategies to handle it efficiently. One prevalent strategy is known as read-through caching:</p>
<ol>
<li>Request Received: The web server gets a request from a client.</li>
<li>Check Cache: It first looks into the cache to see if the response to the request is already there.</li>
<li>Cache Hit: If the response is in the cache (hit), it sends the data back to the client right away.</li>
<li>Cache Miss: If the response isn’t in the cache (miss), the server queries the database to fetch the required data.</li>
<li>Store in Cache: Once it gets the data from the database, it stores the response in the cache for future requests.</li>
<li>Send Response: Finally, the server sends the data back to the client.</li>
</ol>
<h3 id="heading-what-to-consider-when-implementing-a-cache-system">What to Consider When Implementing a Cache System</h3>
<h4 id="heading-decide-when-to-use-a-cache">Decide When to Use a Cache:</h4>
<ul>
<li>A cache is best for frequently read but infrequently modified data.</li>
<li>Cache servers are not suitable for storing critical data as they use volatile memory.</li>
<li>Important data should be stored in persistent data stores to prevent loss in case of cache server restarts.</li>
</ul>
<h4 id="heading-set-an-expiration-policy">Set an Expiration Policy:</h4>
<ul>
<li>Implement an expiration policy to remove expired data from the cache.</li>
<li>Avoid setting expiration dates too short (to prevent frequent database reloads), and too long (to prevent stale data).</li>
</ul>
<h4 id="heading-maintain-synchronization-between-data-stores-and-cache">Maintain Synchronization Between Data Stores and Cache</h4>
<ul>
<li>Inconsistencies can arise due to separate operations on data storage and cache, especially in distributed environments.</li>
</ul>
<h4 id="heading-mitigate-failures">Mitigate Failures:</h4>
<ul>
<li>Use multiple cache servers across different data centers to avoid single points of failure.</li>
<li>Over-provision memory to accommodate increased usage and prevent performance issues.</li>
</ul>
<h4 id="heading-implement-an-eviction-policy">Implement an Eviction Policy:</h4>
<ul>
<li>When the cache is full, new items may cause existing ones to be removed (cache eviction).</li>
<li>A popular eviction policy is Least Recently Used (LRU), but other policies like Least Frequently Used (LFU) or First In, First Out (FIFO) can be chosen based on specific use cases.</li>
</ul>
<h3 id="heading-real-world-applications-of-caching">Real-World Applications of Caching</h3>
<p><strong>Social Media Platforms:</strong> Imagine scrolling through your Facebook feed. Thanks to caching, you see profile pictures, trending posts, and recently liked content instantly, even if millions of users are accessing the platform simultaneously. </p>
<p>Caching these frequently accessed elements on servers or your device minimizes delays and makes the experience smoother and more engaging.</p>
<p><strong>E-commerce Websites:</strong> When browsing Amazon for a new gadget, you expect a seamless shopping experience. Caching plays a crucial role here. Product images, descriptions, and pricing information are cached, enabling the website to display search results and product pages rapidly. </p>
<p>This is especially crucial during peak seasons like Black Friday or Cyber Monday, where caching helps handle surges in traffic and ensures customers can complete their purchases without encountering delays.</p>
<p><strong>Content Management Systems (CMS):</strong> Millions of websites rely on CMS platforms like WordPress. To ensure smooth performance for all these users, many CMS platforms integrate caching plugins. These plugins cache frequently accessed pages, reducing the load on the server and database. </p>
<p>This translates to faster page loading times, improved SEO ranking due to faster indexing by search engines, and a more responsive website overall, providing a better experience for visitors.</p>
<h2 id="heading-what-is-a-content-delivery-network-cdn">What is a Content Delivery Network (CDN)?</h2>
<p>Now, think of a CDN as a global network of book delivery trucks. Instead of storing all the books in one central library, you have local branches worldwide, each with copies of the most popular books. </p>
<p>When readers request a book, you don’t have to ship it from the main library. Instead, you direct them to the nearest branch, where they can quickly pick up a copy. This cuts down on travel time (data transfer time) and keeps everyone happy with fast access to their favorite books.</p>
<p>In technical terms, a CDN is a network of servers distributed across various locations globally. Its primary purpose is to deliver web content, such as images, videos, scripts, and stylesheets to users more efficiently by reducing the physical distance between the server and the user.</p>
<h3 id="heading-how-cdns-work">How CDNs Work:</h3>
<p>First, imagine that User A wants to see an image on a website. They click on a link provided by the CDN, like “<a target="_blank" href="https://mysite.cloudfront.net/logo.jpg">https://mywebsite.cloudfront.net/image.jpg</a>". This requests the image.</p>
<p>Then, if the image isn’t in the CDN’s storage (cache), the CDN fetches the image from the original source, like a web server or Amazon S3.</p>
<p>In response to that, the original source sends the image back to the CDN. It might include a Time-to-Live (TTL) header, indicating how long the image should stay cached.</p>
<p>Next, the the CDN stores the image and serves it to User A. It stays cached until the TTL expires.</p>
<p>Then let's say that user B requests the same image. At that point, the CDN checks if it’s still in the cache. If the image is still cached (TTL hasn’t expired), the CDN serves it from there (a hit). Otherwise (a miss), it fetches a fresh copy from the origin.</p>
<h3 id="heading-what-to-consider-when-implementing-a-cdn">What to Consider When Implementing a CDN</h3>
<ul>
<li><strong>Cost Management</strong>: CDNs charge for data transfers. It’s wise to cache frequently accessed content, but not everything.</li>
<li><strong>Cache Expiry</strong>: Set appropriate cache expiry times. Too long, and content might be stale. Too short, and it strains origin servers.</li>
<li><strong>CDN Fallback</strong>: Plan for CDN failures. Ensure your website can switch to fetching resources directly from the origin if needed.</li>
<li><strong>Invalidating Files</strong>: You can remove files from the CDN before they expire using various methods provided by CDN vendors.</li>
</ul>
<h3 id="heading-real-world-applications-of-a-cdn">Real-World Applications of a CDN</h3>
<p><strong>Video Streaming Services:</strong> Imagine you're in Sydney, Australia, craving to watch the latest season of your favorite show on Netflix. Without a CDN, the data would have to travel all the way from a server in, say, California, leading to buffering and frustrating delays. </p>
<p>But thanks to CDNs, Netflix caches popular content on edge servers closer to you, in Sydney or its surrounding region. This significantly reduces the distance the data needs to travel, ensuring smooth playback and an uninterrupted viewing experience, regardless of your location. </p>
<p>In fact, studies show that CDNs can <strong>reduce video startup time by up to 50%</strong>, making a significant difference in user satisfaction.</p>
<p><strong>Gaming Content Distribution:</strong> Gamers know the pain of waiting for massive game updates or DLC downloads. But companies like Steam and Epic Games leverage CDNs to make things faster. </p>
<p>These platforms cache game files, updates, and multiplayer assets on edge servers close to gaming communities. This means whether you're downloading a new game in New York or patching your favorite title in Tokyo, the data doesn't have to travel across continents. </p>
<p>Using CDNs can decrease download times quite a bit, leading to quicker access to the games you love and smoother multiplayer experiences with minimal lag.</p>
<p><strong>Global News Websites:</strong> Staying informed about global events shouldn't be hindered by slow loading times. Major news organizations like BBC News and The New York Times use CDNs to ensure their breaking news updates and multimedia content reach audiences worldwide instantly. </p>
<p>By caching critical information like articles, videos, and images on servers across different continents, CDNs enable news websites to deliver real-time updates quickly, keeping readers informed regardless of their location. </p>
<p>During major events or emergencies, this can be especially crucial, as evidenced by a case study where a news organization using a CDN reported a <strong>20% increase in website traffic without any performance issues</strong> during a breaking news event.</p>
<h2 id="heading-caching-vs-cdns-whats-the-difference">Caching vs CDNs – What's the Difference?</h2>
<h3 id="heading-similarities-between-caching-and-cdns">Similarities between caching and CDNs:</h3>
<p><strong>Improved Performance:</strong> Both CDNs and caching aim to enhance website performance by reducing latency and speeding up content delivery.</p>
<p><strong>Efficient Resource Utilization:</strong> By serving cached or replicated content, both approaches help optimize resource utilization and reduce server load.</p>
<p><strong>Enhanced User Experience:</strong> Faster load times lead to a better user experience, whether achieved through CDNs or caching.</p>
<h3 id="heading-differences-between-caching-and-cdns">Differences between Caching and CDNs</h3>
<h4 id="heading-scope">Scope:</h4>
<ul>
<li>CDNs: CDNs are a network of servers located in different geographic locations around the world.</li>
<li>Caching: Caching is a method of storing web content on a user’s local device or server.</li>
</ul>
<h4 id="heading-implementation">Implementation:</h4>
<ul>
<li>CDNs: CDNs require a separate infrastructure and configuration.</li>
<li>Caching: Caching can be implemented within a web application or server using caching rules and directives.</li>
</ul>
<h4 id="heading-geographic-coverage">Geographic Coverage:</h4>
<ul>
<li>CDNs: Designed to deliver web content to users across the world.</li>
<li>Caching: Typically used to improve performance for individual users or within a local network.</li>
</ul>
<h4 id="heading-network-architecture">Network Architecture:</h4>
<ul>
<li>CDNs: Use a distributed network of servers to cache and deliver content.</li>
<li>Caching: This can be implemented using various types of storage such as local disk, memory, or a server-side cache.</li>
</ul>
<h4 id="heading-performance-benefits">Performance Benefits:</h4>
<ul>
<li>CDNs: Provide faster and more reliable content delivery by caching content in multiple locations.</li>
<li>Caching: Improves performance by reducing the number of requests to the origin server and delivering content faster from a local cache.</li>
</ul>
<h4 id="heading-cost">Cost:</h4>
<ul>
<li>CDNs: Can be more expensive to implement and maintain due to the need for a separate infrastructure and ongoing costs for network maintenance.</li>
<li>Caching: Can be implemented using existing infrastructure and server resources, potentially reducing costs.</li>
</ul>
<h2 id="heading-when-to-use-caching">When to use Caching</h2>
<p>Caching is ideal for frequently accessed content that doesn't change frequently. This includes static assets like images, CSS files, and JavaScript libraries.</p>
<p>It's particularly effective for websites with a substantial user base accessing similar content, such as news websites, blogs, and e-commerce platforms.</p>
<p>Caching can also significantly reduce server load and improve response times for users, especially in scenarios where content delivery latency is a concern.</p>
<h2 id="heading-when-to-use-cdns">When to use CDNs</h2>
<p>CDNs are invaluable for delivering content to a global audience, especially when geographical distance between users and origin servers leads to latency issues.</p>
<p>They are well-suited for serving dynamic content, streaming media, and handling sudden spikes in traffic.</p>
<p>CDNs also excel in scenarios where content needs to be delivered reliably and consistently across diverse geographic regions, ensuring optimal user experience regardless of location.</p>
<h2 id="heading-combining-caching-and-cdns">Combining Caching and CDNs</h2>
<p>In many scenarios, employing both caching and CDNs together yields optimal results, particularly for dynamic websites and applications where a mix of static and dynamic content delivery is essential. Let's consider a popular news website as an example.</p>
<p>Imagine a bustling news website that regularly publishes breaking news articles, accompanied by images and videos. While the core news content is dynamic and frequently updated, the images and videos associated with older articles remain relatively static and are accessed repeatedly by users.</p>
<p>To address this, the website can implement a combined strategy:</p>
<ol>
<li><strong>Caching on the Origin Server:</strong> Frequently accessed elements like website templates, navigation menus, and static content are cached directly on the origin server. This caching reduces server load and enhances performance for initial page loads.</li>
<li><strong>CDN Caching:</strong> The website leverages a CDN to cache frequently accessed images and videos associated with news articles on edge servers located worldwide. This ensures that users, regardless of their geographic location, can swiftly access these elements with minimal latency.</li>
</ol>
<p>There are many benefits of the combined approach, such as:</p>
<ul>
<li><strong>Faster Loading Times:</strong> By serving cached content from both the origin server and CDN edge servers, users experience significantly faster loading times, leading to a more engaging browsing experience.</li>
<li><strong>Reduced Server Load:</strong> Caching alleviates pressure on the origin server, enabling it to efficiently process dynamic content updates while serving static elements from cache.</li>
<li><strong>Improved Global Reach:</strong> The CDN ensures that users worldwide can access the website and its content with minimal delays, irrespective of their proximity to the origin server.</li>
</ul>
<p>But there are also some factors to consider:</p>
<ul>
<li><strong>Cache Invalidation:</strong> Regularly updating cached content ensures users access the latest information. Most CDNs offer efficient cache invalidation mechanisms to facilitate this process.</li>
<li><strong>Cost Optimization:</strong> While combining caching and CDNs enhances performance, it's crucial to evaluate the cost-effectiveness of caching specific content. Analyzing user access patterns helps determine the optimal caching strategy.</li>
</ul>
<p>By strategically combining caching and CDNs, you and your team can create a robust content delivery infrastructure that delivers a superior user experience worldwide.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Both CDNs and caching play crucial roles in optimizing website performance and user experience by speeding up content delivery. </p>
<p>While caching stores frequently accessed data locally for quick retrieval, CDNs provide a geographically distributed network of servers to deliver content efficiently to users worldwide. </p>
<p>Understanding their similarities in performance improvement and resource utilization, as well as their key differences in scope, implementation, and cost is crucial for choosing the right approach for your specific needs.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How CDNs Help Speed Up Performance by Reducing Latency ]]>
                </title>
                <description>
                    <![CDATA[ By Austin Gil In some recent tutorials, I covered supporting file uploads on the front end, supporting file uploads on the back end, and optimizing costs by moving file uploads to object storage. Today, I'll continue to focus on more architectural wo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/cdns-speed-up-performance-by-reducing-latency/</link>
                <guid isPermaLink="false">66d45d98052ad259f07e4a59</guid>
                
                    <category>
                        <![CDATA[ content delivery network  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 27 Jun 2023 00:17:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/pexels-pixabay-315934.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Austin Gil</p>
<p>In some recent tutorials, I covered <a target="_blank" href="https://austingil.com/uploading-files-with-html/">supporting file uploads on the front end</a>, <a target="_blank" href="https://austingil.com/file-uploads-in-node/">supporting file uploads on the back end</a>, and optimizing costs by <a target="_blank" href="https://austingil.com/upload-to-s3/">moving file uploads to object storage.</a></p>
<p>Today, I'll continue to focus on more architectural work, but this time it’ll be focused on optimizing performance.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Vymnxp-t0qs" 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-overview-of-object-storage-solution">Overview of Object Storage Solution</h2>
<p>Let's say we have an application that stores uploaded files somewhere in the world. For this example, it’s an <a target="_blank" href="https://www.linode.com/products/object-storage/">Object Storage bucket from Akamai cloud computing services</a>, and I've deployed it to the <code>us-southeast-1</code> region.</p>
<p>You may be using a different provider and different region, but the following points will still apply.</p>
<p>So when I upload a cute photo of Nugget making a big ol’ yawn, I'll be able to access it at some URL like austins-bucket.us-southeast-1.linodeobjects.com/files/nugget.jpg</p>
<p><img src="https://austingil.com/wp-content/uploads/image-65-1080x608.png" alt="Screenshot of my browser showing a cute photo of Nugget making a big yawn, and there's a box highlighting the URL from Akamai Object Storage." width="1080" height="608" loading="lazy"></p>
<p>Nugget is a super cute dog. Naturally, a lot of people are going to want to see this. Unfortunately, because this photo is hosted in the <code>us-southeast-1</code> region, anyone that lives far away from that region has to wait longer before their eyes can feast on this beast.</p>
<p>Latency sucks.</p>
<p>And that’s why CDNs exist.</p>
<h2 id="heading-what-is-a-cdn">What is a CDN?</h2>
<p>CDN stands for "<strong>content delivery network</strong>". It’s a connected network of computers that are globally distributed and can store copies of the same files so that when a user makes a request for a specific file, it can be served from the nearest computer to the user. </p>
<p>By using a CDN, the distance a request must travel is reduced. This helps resolve requests faster, regardless of a user’s location.</p>
<p>Here’s a <a target="_blank" href="https://www.webpagetest.org/result/230417_BiDc3J_AP8/">webpagetest.org test results</a> for that photo of Nugget. The request was made from their servers in Japan, and it took 1.1 seconds for the request to complete.</p>
<p><img src="https://austingil.com/wp-content/uploads/image-69-1080x723.png" alt="Image" width="1080" height="723" loading="lazy"></p>
<p>Instead of serving the file directly from my Object Storage bucket, I can set up a CDN in front of my application to cache the photo all over the world.</p>
<p>So users in Tokyo will get the same photo but served from their nearest CDN location (which is probably in Tokyo), and users in Toronto are going to get that same file, but served from their nearest CDN location (which is probably in Toronto).</p>
<p>This can have significant performance implications.</p>
<p>Let’s look at that same request, but served behind a CDN. The <a target="_blank" href="https://www.webpagetest.org/result/230417_BiDc41_ARJ/">webpagetest.org results</a> still show the same photo of Nugget, and the request still originated from Tokyo, but this time it only took 0.2 seconds – <strong>a fraction of the time!</strong></p>
<p><img src="https://austingil.com/wp-content/uploads/image-68-1080x956.png" alt="Image" width="1080" height="956" loading="lazy"></p>
<p>When the request is made for this image, the CDN can check if it already has a cached version. If it does, it can respond immediately. If it doesn’t, it can go fetch the original file from Object Storage, then save a cached version for any future requests.</p>
<p><strong>Note</strong>: the numbers reported above are from a single test. They may vary depending on network conditions.</p>
<h2 id="heading-the-compounding-returns-of-cdns">The Compounding Returns of CDNs</h2>
<p>The example above focused on improving delivery speeds of uploaded files. In that context, I was only dealing with a single image that is uploaded to an Object Storage bucket. It shows almost a full second improvement in response times, which is great, but things get even better when you consider other types of assets.</p>
<p>CDNs are great for any static asset (CSS, JavaScript, fonts, images, icons, and so on). By putting it in front of my application, all the other static files can automatically get cached as well. This includes the files that Nuxt.js generates in the build process, and which are hosted on the application server.</p>
<p>This is especially relevant when you consider the “<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/Performance/Critical_rendering_path">Critical rendering path</a>” and render-blocking resources like CSS, JavaScript, or fonts.</p>
<p>When a webpage loads, as the browser comes across a render-blocking resource, it will pause parsing and go download the resource before it continues (hence “render-blocking”). So any latency that affects a single asset may also impact the performance of other assets further down the network cascade.</p>
<p>This means the performance improvements from a CDN are compounding. Nice!</p>
<p>So is this about showing cute photos of my dog to more people even faster, or is it about helping you make your applications run faster? YES!</p>
<p>Whatever motivates you to build faster websites, including a CDN as part of your application infrastructure is a crucial step if you plan on serving customers from more than one region.</p>
<h2 id="heading-how-to-connect-akamai-cdn-to-object-storage">How to Connect Akamai CDN to Object Storage</h2>
<p>Now I want to take a little side-quest and share how I set up Akamai with Object Storage. I didn’t find much information on the subject, and I’d like to help anyone in this specific situation. If it doesn’t apply to your use case, feel free to skip this section.</p>
<p>With something like 300,000 servers across 4,000 locations, Akamai is the largest CDN provider in the world. It’s used by some of the biggest companies in the world, but it’s hard to find Akamai-related content because most large companies don't like to share unnecessary information about their infrastructure.</p>
<p>But I'm not most companies :)</p>
<p>(Note: You will need an Akamai account and access to your DNS editor)</p>
<p>In the <a target="_blank" href="https://control.akamai.com/">Akamai Control Center</a>, I created <a target="_blank" href="https://control.akamai.com/apps/create/#/property/products">a new Property</a> using the <a target="_blank" href="https://www.akamai.com/products/web-performance-optimization">Ion Standard product,</a> which is great for general purpose CDN delivery.</p>
<p><img src="https://austingil.com/wp-content/uploads/image-71-1080x274.png" alt="Image" width="1080" height="274" loading="lazy"></p>
<p>After clicking “Create Property”, you’ll be prompted to choose whether to use the setup wizard to guide you through creating the property, or you can go straight to the Property Manager settings for the new property. I chose the latter.</p>
<p>In the Property Manager, I had to add a new hostname in the Property Hostnames section. I added the hostname for my application. This is the URL where users will find your application. In my case, it was uploader.austingil.com.</p>
<p><img src="https://austingil.com/wp-content/uploads/image-76-1080x520.png" alt="Image" width="1080" height="520" loading="lazy"></p>
<p>Part of this process also requires setting up an SSL certificate for the hostname. I left the default value selected for Enhanced TLS.</p>
<p><img src="https://austingil.com/wp-content/uploads/image-77-1080x520.png" alt="Image" width="1080" height="520" loading="lazy"></p>
<p>With all that set up, Akamai will show me the following Property Hostname and Edge Hostname. We’ll come back to these later when it’s time to make DNS changes.</p>
<ul>
<li><strong>Property Hostname:</strong> uploader.austingil.com</li>
<li><strong>Edge Hostname:</strong> uploader.austingil.com-v2.edgekey.net</li>
</ul>
<p><img src="https://austingil.com/wp-content/uploads/image-72-1080x155.png" alt="Image" width="1080" height="155" loading="lazy"></p>
<p>Next, I had to set up the actual property’s behavior, which meant editing the Default Rule under the Property Configuration Settings. Specifically, I had to point the <strong>Origin Server Hostname</strong> to the domain where my origin server will live.</p>
<p><img src="https://austingil.com/wp-content/uploads/image-73-1080x761.png" alt="Image" width="1080" height="761" loading="lazy"></p>
<p>In my DNS, I created a new A record pointing origin-uploader.austingil.com to my origin server’s IP address, then added a CNAME record that points uploader.austingil.com to the Edge Hostname provided by Akamai.</p>
<ul>
<li>A: origin-uploader.austingil.com -&gt; origin server IP</li>
<li>CNAME: uploader.austingil.com -&gt; uploader.austingil.com-v2.edgekey.net</li>
</ul>
<p>This lets me build out my CDN configuration and test it as needed, only sending traffic through the CDN when I’m ready.</p>
<p>Finally, to serve files in my Object Storage instance through Akamai, I created a new rule based on the blank rule template. I set the rule criteria to apply to all requests going to the <code>/files/*</code> sub-route.</p>
<p><img src="https://austingil.com/wp-content/uploads/image-74-1080x402.png" alt="Image" width="1080" height="402" loading="lazy"></p>
<p>The rule behavior is set up to rewrite the request’s Origin Server Hostname and change it to my Object Storage location: npm.us-southeast-1.linodeobjects.com.</p>
<p><img src="https://austingil.com/wp-content/uploads/image-75-1080x602.png" alt="Image" width="1080" height="602" loading="lazy"></p>
<p>This way, any request that goes to <a target="_blank" href="https://uploader.austingil.com/files/nugget.jpg">uploader.austingil.com/files/nugget.jpeg</a> is served <strong>through</strong> the CDN, but the file originates from the Object Storage location. And when you load the application, all the static assets generated by Nuxt are served from the CDN as well. All other requests are passed through Akamai and forwarded to origin-uploader.austingil.com, which points to the origin server.</p>
<p>So that’s how I’ve configured Akamai CDN to sit in front of my application. Hopefully, it all made sense, but if you have questions, feel free to ask me.</p>
<h2 id="heading-to-sum-up">To Sum Up</h2>
<p>Today we looked at what a CDN is, the role it plays in reducing network latency, and how to set up Akamai CDN with Object Storage.</p>
<p>But this is just the tip of the iceberg. There’s a whole world of tweaking CDN configuration to get even more performance. </p>
<p>There are also a lot of other performance and security features a CDN can offer beyond just static file caching: Web Application Firewalls, faster network path resolution, <a target="_blank" href="https://www.akamai.com/solutions/security/ddos-protection">DDoS protection</a>, bot mitigation, <a target="_blank" href="https://www.akamai.com/solutions/edge">edge compute</a>, automated <a target="_blank" href="https://www.akamai.com/products/image-and-video-manager">image and video optimization</a>, malware scanning, request security headers, and more. </p>
<p>My colleague <a target="_blank" href="https://www.linkedin.com/in/mikeelissen/">Mike Elissen</a> also covers some great security topics <a target="_blank" href="https://blog.securitylevelup.eu/">on his blog</a>.</p>
<p>The most important thing that I wanted to convey today is that using a CDN improves file delivery performance by caching content close to the user.</p>
<p>Thank you so much for reading. If you liked this article, and want to support me, the best ways to do so are to <a target="_blank" href="https://twitter.com/share?via=heyAustinGil">share it</a>, <a target="_blank" href="https://austingil.com/newsletter/">sign up for my newsletter</a>, and <a target="_blank" href="https://twitter.com/heyAustinGil">follow me on Twitter</a>.</p>
<p><em>You can find this and my other articles published on <a target="_blank" href="https://austingil.com/file-uploads-cdn/">austingil.com</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Import JavaScript and CSS from a Public CDN ]]>
                </title>
                <description>
                    <![CDATA[ By Alan Richardson When you're writing a Vanilla JavaScript application, you don't have to host all the code you use on your own site.  Most popular JavaScript libraries are available from a public Content Delivery Network (CDN).  This can simplify d... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/import-javascript-and-css-from-a-public-cdn/</link>
                <guid isPermaLink="false">66d45d5b677cb8c6c15f3150</guid>
                
                    <category>
                        <![CDATA[ content delivery network  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 09 Feb 2022 00:38:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/02/cdn-imports-for-javascript.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Alan Richardson</p>
<p>When you're writing a Vanilla JavaScript application, you don't have to host all the code you use on your own site. </p>
<p>Most popular JavaScript libraries are available from a public Content Delivery Network (CDN). </p>
<p>This can simplify deploying the application and keeping dependencies up to date. In fact, if you've followed any JavaScript tutorial for a library, then you've probably already used a public CDN but may not be aware of it.</p>
<h2 id="heading-what-is-a-cdn">What is a CDN?</h2>
<p>A CDN is a Content Delivery Network. These are file hosting services for multiple versions of common libraries. They are usually highly performant and offer location cached files so no matter where your users are, they receive the files from geo locations close to them. This can make your application faster than hosting files yourself.</p>
<p>CDN's also have the advantage that if you are using libraries common to multiple sites then your users may already have the file cached in their browser. This speeds up your site because the browser doesn't need to download the library again.</p>
<p>For example, JQuery has an <a target="_blank" href="https://releases.jquery.com/">official JQuery CDN</a>. If most JQuery applications import the JQuery library from this CDN, then users are more likely to have JQuery in their cache already.</p>
<h2 id="heading-npm-driven-cdns"><code>npm</code>-driven CDNs</h2>
<p>Not every library has their own CDN. Most libraries deploy to <a target="_blank" href="https://npmjs.com">npmjs.com</a> and rely on the programmer adding the library to their project via <code>npm</code> at build time. <code>npm</code> downloads the library from a CDN and adds it to the project locally.</p>
<p>We don't have to be using <code>npm</code> and JavaScript build processes to take advantage of the <code>npm</code> eco-system. We can use an 'npm driven CDN' as the host for libraries, without having to use <code>npm</code>.</p>
<p>An 'npm-driven CDN' is one which hosts the distribution code for libraries which deploy to <code>npm</code>.</p>
<p>For example, <a target="_blank" href="https://ag-grid.com">AG Grid</a> which I demonstrated in my article "<a target="_blank" href="https://www.freecodecamp.org/news/convert-html-table-to-dynamic-javascript-data-grid/">How to Convert a Static HTML Table to a Dynamic JavaScript Data Grid</a>" deploys to <code>npm</code> but does not have its own CDN. Instead, programmers can add a direct reference to AG Grid from a CDN like <a target="_blank" href="https://unpkg.com/">unpkg.com</a>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=
<span class="hljs-string">"https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.nostyle.js"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p><code>npm</code>-driven CDNs monitor the releases distributed via <code>npm</code>, and host the releases on their own site.</p>
<p>In the source code for my earlier freeCodeCamp post, I used the unpkg.com CDN to import AG Grid in my code using a <code>script</code> element. </p>
<p>As with all code that we copy and paste, it's worth understanding what it does so that we can handle any issues.</p>
<h2 id="heading-what-cdns-are-available">What CDNs are available?</h2>
<p>I've only ever used three CDNs:</p>
<ul>
<li><a target="_blank" href="https://unpkg.com">Unpkg.com</a></li>
<li><a target="_blank" href="https://www.jsdelivr.com">jsDelivr.com</a></li>
<li><a target="_blank" href="https://cdnjs.com">cdnjs.com</a></li>
</ul>
<p>These are all professional and well-run sites. And the main reason I pick one above the other is that the tutorial I first followed for a library used that particular CDN in the code.</p>
<p>Knowing that multiple CDNs are available is useful because:</p>
<ul>
<li>a particular version of a library you want to use might not be on every CDN</li>
<li>if a CDN starts having issues then you can amend your code to use another</li>
<li>some libaries may be more popular on one CDN than another and you may want to use the most popular CDN to increase the chance that the JavaScript library code is cached on your users's browser.</li>
</ul>
<h2 id="heading-npm-cdns-distribute-more-than-javascript"><code>npm</code> CDNs distribute more than JavaScript</h2>
<p>CDNs deliver more than JavaScript. For example, AG Grid deploys CSS files as well as JavaScript.</p>
<p>These would be referenced from the CDN as normal using <code>link</code> elements.</p>
<p>For example, AG Grid uses two style sheets.</p>
<p>The Structural Style sheet provides the CSS that will layout the data as a Grid.</p>
<pre><code>&lt;link 
 rel=<span class="hljs-string">"stylesheet"</span>
 href=<span class="hljs-string">"https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css"</span>
&gt;
</code></pre><p>The Theme Style sheet provides the visual aesthetics for the Grid.</p>
<pre><code>&lt;link 
 rel=<span class="hljs-string">"stylesheet"</span> 
 href=<span class="hljs-string">"https://unpkg.com/ag-grid-community/dist/styles/ag-theme-alpine.css"</span>
&gt;
</code></pre><p>Both of these CSS files are also deployed to npmjs.com and can be included into our project from a CDN.</p>
<h2 id="heading-how-and-why-to-control-the-version-of-the-library">How (and Why) to Control the Version of the Library</h2>
<p>In my <a target="_blank" href="https://eviltester.github.io/grid-table-editor/#">open source table editing tool</a> I use three libraries: AG Grid, PapaParse, and Faker.</p>
<p>Faker recently had an issue where a recent version deployed to npm had issues. So if my code had been defaulting to the latest version then my application would have failed.</p>
<p>Fortunately I had imported a specific version of faker from unpkg. As you can see from the <code>src</code> URL below I included version <code>5.5.3</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=
    <span class="hljs-string">"https://unpkg.com/faker@5.5.3/dist/faker.min.js"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>There are number of advantages to controlling the version:</p>
<ul>
<li>you will have tested your application on a specific version. If you deploy to production and allow the version to change with every new release, then your application may gradually exhibit bugs or incompatibilities over time because you haven't tested your application against the new version of the library.</li>
<li>when using multiple versions of libraries, future versions may conflict with each other, again causing your application to fail in production and possibly without you noticing.</li>
</ul>
<p>I import the three libraries I use at specific versions:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/ag-grid-community@26.2.1/dist/ag-grid-community.min.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">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/papaparse@5.3.0/papaparse.min.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">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/faker@5.5.3/dist/faker.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>This puts me in control of the testing and I'm more confident that any bugs in the application will be a result of my coding, rather than an update to a library used in the project.</p>
<p>The different CDNs may have a different syntax for controlling the version numbers. But you will be able to see the format to use by searching for the library on the CDN and following the documentation provided by each CDN.</p>
<p>Here are the listings for AG Grid on each of the CDN sites:</p>
<ul>
<li><a target="_blank" href="https://unpkg.com/ag-grid-community/">Unpkg.com - AG Grid</a></li>
<li><a target="_blank" href="https://www.jsdelivr.com/package/npm/ag-grid-community">jsDelivr.com - AG Grid</a></li>
<li><a target="_blank" href="https://cdnjs.com/libraries/ag-grid">cdnjs.com - AG Grid</a></li>
</ul>
<p>If you follow the links for the AG Grid packages then you will see that each site has a slightly different interface. But they all allow selecting a specific version of AG Grid and allow you to copy and paste the URL to add to your HTML file.</p>
<h2 id="heading-cdn-in-practice">CDN in Practice</h2>
<p>Below is a simple HTML file which will render a Data Grid on the screen.</p>
<p>I only have to deploy the HTML file, because the AG Grid library is loaded into the browser from the CDN.</p>
<p>In the example below I'm loading version 26.2.1 of AG Grid and the CSS files from the <strong>unpkg.com CDN</strong>.</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">title</span>&gt;</span>CDN Added AG Grid Example<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/ag-grid-community@26.2.1/dist/ag-grid-community.min.nostyle.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">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://unpkg.com/ag-grid-community@26.2.1/dist/styles/ag-grid.css"</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://unpkg.com/ag-grid-community@26.2.1/dist/styles/ag-theme-alpine.css"</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">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myGrid"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"height: 200px; width:500px;"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"ag-theme-alpine"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'DOMContentLoaded'</span>, <span class="hljs-function">() =&gt;</span> {

    <span class="hljs-keyword">const</span> columnDefs = [
        { <span class="hljs-attr">field</span>: <span class="hljs-string">"cdn"</span> },
        { <span class="hljs-attr">field</span>: <span class="hljs-string">"url"</span> },
    ];

    <span class="hljs-keyword">const</span> rowData = [
        { <span class="hljs-attr">cdn</span>: <span class="hljs-string">"jsDelivr"</span>, <span class="hljs-attr">url</span>: <span class="hljs-string">"https://www.jsdelivr.com"</span>},
        { <span class="hljs-attr">cdn</span>: <span class="hljs-string">"Unpkg"</span>, <span class="hljs-attr">url</span>: <span class="hljs-string">"https://Unpkg.com"</span> },
        { <span class="hljs-attr">cdn</span>: <span class="hljs-string">"cdnJS"</span>, <span class="hljs-attr">url</span>: <span class="hljs-string">"https://cdnjs.com"</span> }
    ];


    <span class="hljs-keyword">const</span> gridOptions = {
        <span class="hljs-attr">columnDefs</span>: columnDefs,
        <span class="hljs-attr">rowData</span>: rowData,
        <span class="hljs-comment">/* allow manual copy and paste */</span>
        <span class="hljs-attr">enableCellTextSelection</span>:<span class="hljs-literal">true</span>,
        <span class="hljs-attr">ensureDomOrder</span>:<span class="hljs-literal">true</span>
    };


    <span class="hljs-keyword">const</span> gridDiv = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#myGrid'</span>);
    <span class="hljs-keyword">new</span> agGrid.Grid(gridDiv, gridOptions);
});
</span><span class="hljs-tag">&lt;/<span class="hljs-name">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><a target="_blank" href="https://eviltester.github.io/freecodecampexamples/javascript-cdns/adding-ag-grid-from-unpkg.html">Unpkg imports are demonstrated in this deployed html page.</a></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/cdn-urls.png" alt="cdns and their urls" width="600" height="400" loading="lazy"></p>
<p>I could easily use other CDNs by changing the <code>script</code> and <code>link</code> elements in the <code>head</code> section of my <code>html</code> file.</p>
<p><strong>JSDelivr</strong> using version 26.2.1</p>
<ul>
<li>https://cdn.jsdelivr.net/npm/ag-grid-community@26.2.1/dist/ag-grid-community.min.noStyle.js</li>
<li>https://cdn.jsdelivr.net/npm/ag-grid-community@26.2.1/dist/styles/ag-grid.css</li>
<li>https://cdn.jsdelivr.net/npm/ag-grid-community@26.2.1/dist/styles/ag-theme-alpine.css</li>
</ul>
<p><a target="_blank" href="https://eviltester.github.io/freecodecampexamples/javascript-cdns/adding-ag-grid-from-jsdelivr.html">JSDelivr imports are demonstrated in this deployed html page.</a></p>
<p><strong>CdnJS</strong> using version 26.2.1. CdnJS takes a slightly different approach to version naming so it is worth checking the version drop down on the <a target="_blank" href="https://cdnjs.com/libraries/ag-grid">cdnJS AG Grid listing</a></p>
<ul>
<li>https://cdnjs.cloudflare.com/ajax/libs/ag-grid/Docs-26.2.0-20211117/ag-grid-community.min.noStyle.min.js</li>
<li>https://cdnjs.cloudflare.com/ajax/libs/ag-grid/Docs-26.2.0-20211117/styles/ag-grid.min.css</li>
<li>https://cdnjs.cloudflare.com/ajax/libs/ag-grid/Docs-26.2.0-20211117/styles/ag-theme-alpine.min.css</li>
</ul>
<p><a target="_blank" href="https://eviltester.github.io/freecodecampexamples/javascript-cdns/adding-ag-grid-from-cdnjs.html">CdnJS imports are demonstrated in this deployed html page.</a></p>
<h2 id="heading-summary">Summary</h2>
<p>We don't always have to deploy JavaScript libraries to our site along with our HTML files. Instead, we can include them such that they are delivered by a Content Delivery Network.</p>
<p>Many tutorials we follow will show examples of doing this.</p>
<p>If we do import JavaScript or CSS from a CDN we should add the version number of the library that we are using to protect our deployed example from future issues if the library updates.</p>
<p>A good habit to get into is adding the version evern when we follow a tutorial. If we notice that the CDN included files do not have a version, then it is worth visiting the CDN to find out what the current version of the library is. Then you can add that version number to your source.</p>
<p>It is small adjustments like this that will make any portfolio projects you create on Github a little bit more professional.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Speed Up Your Website with Azure CDN ]]>
                </title>
                <description>
                    <![CDATA[ By Arjav Dave What is a CDN? A Content Delivery Network (CDN) helps you deliver your content more quickly. You can serve any type of content that remains unchanged over a period of time, like images, videos, CSS, JavaScript, HTML files, PDFs, and mor... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-speed-up-your-website-with-azure-cdn/</link>
                <guid isPermaLink="false">66d84de829e30bc0ad477541</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ content delivery network  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Microsoft ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 26 Mar 2021 15:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/03/cdn-cover.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Arjav Dave</p>
<h2 id="heading-what-is-a-cdn">What is a CDN?</h2>
<p>A Content Delivery Network (CDN) helps you deliver your content more quickly. You can serve any type of content that remains unchanged over a period of time, like images, videos, CSS, JavaScript, HTML files, PDFs, and more. </p>
<p>A CDN is a group of servers that are spread across the world to deliver the content from the <em>Edge servers</em>. Edge servers are servers located closest to the place from where the request is being made. </p>
<p>Depending on the request, edge servers may either return the content from its cache or they can fetch it from the <em>Origin Server</em>. The servers that serve the actual content are called Origin servers.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0i7t9e95tryv3mi44ghc.png" alt="CDN Overview" width="1002" height="552" loading="lazy"></p>
<p>In the above image, the Edge Servers are located around the world and the Origin Server is located in California, USA. When a request is made, the Edge Server located at Mumbai, India may contact the Origin Server if it's not able to serve the content.</p>
<h2 id="heading-how-does-a-cdn-work">How Does a CDN Work?</h2>
<p>CDNs have four main parts: a Consumer, a DNS, an Edge Server, and an Origin Server.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gni65528kxlmciivhnyw.png" alt="CDN Detail" width="872" height="552" loading="lazy"></p>
<p>When the Consumer makes a request, it is at first accepted by its Internet Service Provider (ISP). The ISP will then hit the content provider's <em>Authoritative DNS</em>.</p>
<blockquote>
<p>An Authoritative DNS converts the DNS request to an IP request.</p>
</blockquote>
<p>When the Authoritative DNS is made, it returns the IP address of the closest Edge Server. The Edge Server will then check in its own cache to see if the requested content is available. </p>
<p>If it is, then it returns the content. If the content is not available, it requests the content from the Origin Server and on retrieval caches it.</p>
<h2 id="heading-benefits-of-a-cdn">Benefits of a CDN</h2>
<h3 id="heading-low-bandwidth-consumption">Low Bandwidth Consumption</h3>
<p>Many web hosts have a limited bandwidth allocation per month. If you go beyond that you will be charged extra. </p>
<p>With a CDN most of your bandwidth will be saved since the content will be served by the edge servers.</p>
<h3 id="heading-low-latency">Low Latency</h3>
<p>The Edge Servers cache the content. So anytime cached content is requested the latency is reduced drastically. This is because the request doesn't go all the way to the Origin Server.</p>
<h3 id="heading-security-against-ddos">Security against DDoS</h3>
<p>Almost all the popular CDN's have the capability to protect your webserver against Distributed denial of service (DDos) attacks.</p>
<h3 id="heading-improves-seo">Improves SEO</h3>
<p>Loading time is one of the factors that can affect your site's SEO rankings. If you are serving most of your content via CDN, the loading times are drastically reduced and can help improve your SEO.</p>
<h2 id="heading-deep-dive-into-azure-cdn">Deep Dive into Azure CDN</h2>
<p>Let's say you have created an Azure Storage Account and hosted a very simple site that displays Hello World as h1. Now that you know the benefits of CDNs, you want to serve your simple site over CDN. </p>
<p>You will have an endpoint like <em><a target="_blank" href="https://demostorageaccountarjav.z29.web.core.windows.net/">https://demostorageaccountarjav.z29.web.core.windows.net/</a></em> (where instead of demostorageaccountarjav it would be your storage account's name). Here are more details on how to <a target="_blank" href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website">setup a static website</a>.</p>
<p>Login to your Azure Portal and click on <em>Create a resource</em> from you dashboard. Search for <em>CDN</em> which will open the resource in the marketplace as below.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ravgtt3j0xmeu5osd9d2.png" alt="CDN Create Resource" width="1045" height="473" loading="lazy">
<em>Create CDN</em></p>
<p>This will open up a form to create a CDN profile. A CDN profile is a set of CDN endpoints. There is not much to fill in here except the name, resource group, and the pricing tier.</p>
<p>Next, select the checkbox to create a CDN endpoint. An endpoint is where the Consumer will be requesting content. So if you have multiple sites you can create multiple endpoints as well.</p>
<p>I have attached a screenshot for your reference on what values to put in. Since CDN is a global service the region selection will be disabled.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z35xu3l7ox243ea6ecfj.png" alt="CDN Details" width="996" height="881" loading="lazy">
<em>CDN Details</em></p>
<p>You can now click on <em>Create</em> to generate the profile and endpoint. It will take a couple of minutes to create. After it is created and when you go to the home screen, you will have these 4 resources:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6bxldg59sqod68o4kq1.png" alt="Azure Resources" width="1000" height="286" loading="lazy">
<em>Azure Resources</em></p>
<p>As discussed earlier, the CDN Profile is a group of <em>Endpoints</em>. To view the details click the *<em>Endpoint</em> resource. You will see an overview with a link to the <em>Endpoint hostname</em>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vt4t5uxyv6u0i5llicwp.png" alt="Endpoint Overview" width="1300" height="318" loading="lazy">
<em>Endpoint Overview</em></p>
<p>When you open the endpoint hostname it might show "404 not found" initially. You might have to wait another 10-15 minutes before your actual site is visible.</p>
<p>As discussed in the <a class="post-section-overview" href="#heading-benefits-of-a-cdn">benefits</a> section you can configure the Endpoint for security, caching, routing, and a lot of other things. You can explore more options <a target="_blank" href="https://docs.microsoft.com/en-us/azure/cdn/cdn-how-caching-works">here</a>.</p>
<h2 id="heading-how-to-access-via-sas-token">How to Access via SAS Token</h2>
<p>You may be wondering what to do if your resource is in a private container and can only be accessed via a <em>Shared Access Signature</em> (SAS) Token. Well you are in luck! The query strings are passed on as they are and since SAS is as a query string you are good.</p>
<p>Go ahead and create a new storage account (with static website disabled). Add a new Endpoint in the CDN profile that points to the newly created storage account.</p>
<p>For demo purposes I have created a container named <em>site</em> with private access level. And I've uploaded a Blob to it named <em>Photo.jpeg</em> in a Storage Account with the URL <a target="_blank" href="https://demostorageaccountarjav.blob.core.windows.net">https://demostorageaccountarjav.blob.core.windows.net</a>.</p>
<p>You can of course get a SAS token from the Azure portal directly for testing, but that's not how you would usually do in the real world. For that, you'll find below a simple snippet to create a SAS token in Node.js.</p>
<pre><code><span class="hljs-keyword">const</span> azureSasToken = <span class="hljs-built_in">require</span>(<span class="hljs-string">'azure-sas-token'</span>);

<span class="hljs-comment">// default token validity is 7 days</span>
<span class="hljs-keyword">let</span> sasToken = azureSasToken.createSharedAccessToken(<span class="hljs-string">'https://&lt;service namespace&gt;.servicebus.windows.net/&lt;topic name or queue&gt;'</span>,
                                <span class="hljs-string">'&lt;signature key name&gt;'</span>,
                                <span class="hljs-string">'&lt;signature hash&gt;'</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`sasToken: <span class="hljs-subst">${sasToken}</span>`</span>);

<span class="hljs-comment">// Specify your own validity in secs, two hours in this example</span>
sasToken = azureSasToken.createSharedAccessToken(<span class="hljs-string">'https://&lt;service namespace&gt;.servicebus.windows.net/&lt;topic name or queue&gt;'</span>,
                                <span class="hljs-string">'&lt;signature key name&gt;'</span>,
                                <span class="hljs-string">'&lt;signature hash&gt;'</span>, 
                                <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">2</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`sasToken: <span class="hljs-subst">${sasToken}</span>`</span>);
</code></pre><p>We have used a simple npm package named <a target="_blank" href="https://www.npmjs.com/package/azure-sas-token">azure-sas-token</a>. Once the SAS is generated your URL will look something like this:</p>
<pre><code>https:<span class="hljs-comment">//demostorageaccountarjav.blob.core.windows.net/site/Photo.jpeg?sp=r&amp;st=2021-03-25T07:28:45Z&amp;se=2022-02-02T15:28:45Z&amp;spr=https&amp;sv=2020-02-10&amp;sr=b&amp;sig=PD4HlRI8bDEirMevpYQgpx6drwh%2BE5EpILfXkQOMlvw%3D</span>
</code></pre><p>The above URL is pointing directly to the storage account. So go ahead and change the origin so that it uses the origin endpoint.</p>
<pre><code>https:<span class="hljs-comment">//demowebsitearjav.azureedge.net/site/Photo.jpeg?sp=r&amp;st=2021-03-25T07:28:45Z&amp;se=2022-02-02T15:28:45Z&amp;spr=https&amp;sv=2020-02-10&amp;sr=b&amp;sig=PD4HlRI8bDEirMevpYQgpx6drwh%2BE5EpILfXkQOMlvw%3D</span>
</code></pre><p>When you visit this site you will now be able to view the protected resource via CDN. You might have to wait a few minutes and/or purge your Endpoint to see the updated content.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In my opinion everyone should be using a Content Delivery Network. There are lots of other providers like Cloudflare, S3, and so on. But Microsoft is one of the major players emerging with a wide variety of services. </p>
<p>If you are an Azure fan like I am, you should definitely give Azure CDN a try.</p>
<p>For any feedback or questions you can get in touch with me.</p>
<p>Check <a target="_blank" href="https://arjavdave.com">here</a> for more tutorials like this.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Blog Using a Static Site Generator and a CDN ]]>
                </title>
                <description>
                    <![CDATA[ By Aaron Katz I wanted to set up a fun project for myself to learn some new technologies. And this time I decided I wanted to learn a bit about Static Site Generators (SSGs). My goal was to build a blog using an SSG and have it deploy any time ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-blog-using-a-static-site-generator-and-a-cdn/</link>
                <guid isPermaLink="false">66d45d5fbd438296f45cd387</guid>
                
                    <category>
                        <![CDATA[ Blogging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ content delivery network  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Netlify ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Static Site Generators ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 29 Jan 2021 16:46:23 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c95e0740569d1a4ca0ebe.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Aaron Katz</p>
<p>I wanted to set up a fun project for myself to learn some new technologies. And this time I decided I wanted to learn a bit about <strong>Static Site Generators</strong> (SSGs).</p>
<p>My goal was to build a blog using an SSG and have it deploy any time the code repository changed. You can see the result at <a target="_blank" href="https://caliburnsecurity.com">https://caliburnsecurity.com</a>.</p>
<h2 id="heading-blog-requirements">Blog Requirements</h2>
<p>Below are the requirements I put together when determining what I wanted my blog to support.</p>
<ul>
<li>Support Markdown for content generation</li>
<li>Syntax highlighting</li>
<li>Code line numbering</li>
<li>"Serverless"</li>
<li>Ready made themes/plugins - I am so NOT a frontend developer</li>
<li>SEO capabilities</li>
<li>Browse by keyword/category</li>
<li>Search support (because this is statically generated, searching is through Google's index - there are other articles that discuss how to add a dynamic JavaScript powered search)</li>
<li>RSS support</li>
<li>Version controlled</li>
<li>Static - no dynamic content (with a neat side effect of shrinking the site's attack surface and improving security)</li>
</ul>
<h2 id="heading-so-what-actually-is-a-static-site-generator">So what actually is a Static Site Generator?</h2>
<p>In short, an SSG is a framework designed to manage your website and transform it into a site serving only static pages.</p>
<h2 id="heading-why-use-a-ssg-to-build-the-blog">Why use a SSG to build the blog?</h2>
<p>One thing that took me some time to comprehend was why I would use a static site, if I already had a CMS. There were so many articles online about using an SSG with a headless CMS...but why?  </p>
<p>Best I can tell, the benefits are simply that you have more flexibility using familiar frameworks such as React or Vue, while using a CMS to handle all content. </p>
<p>However, as I am by no means a frontend developer, I was close to scrapping this project. I thought "Oh well, I should just use Ghost - it's only $5/month if hosted on a platform like DigitalOcean, and is an all-in-one platform to serve content as well as manage the content".</p>
<p>However, I really wanted to try to learn something new, and see if I could just deploy a blog for free using only Markdown.</p>
<p>As always ends up happening, what I was hoping would take a few hours took quite a bit more time as I went down the rabbit hole of research into various technologies. </p>
<p>I played around with several different technologies, such as (not all of these are SSGs, more on that later):</p>
<ul>
<li>Pelican (Python)</li>
<li>Hugo (Go)</li>
<li>Hexo</li>
<li>Gridsome (Vue - JS)</li>
<li>VuePress (Vue - JS)</li>
<li>Ghost</li>
<li>Gatsby (React - JS)</li>
<li>Jekyll (Ruby)</li>
</ul>
<h3 id="heading-why-i-chose-hugo">Why I Chose Hugo</h3>
<p>I won't go in too much detail on all of the technologies I looked at. But in general, I found Hugo to be super quick to set up and build, and just the <strong>SIMPLEST</strong> of all the options.  </p>
<p>While I know this is similar to Jekyll, I really just didn't want to deal with configuring a Ruby environment, and the speed of Hugo left everything else in the dust.</p>
<h2 id="heading-how-to-start-building-the-blog">How to Start Building the Blog</h2>
<p>For this exercise, let's build a static blog hosted by Netlify (free!).</p>
<p>Note: I'll be using PowerShell on my Windows box for this tutorial, so please recall that if copy/pasting.</p>
<h3 id="heading-make-sure-you-have-these-dependencies">Make sure you have these dependencies:</h3>
<ul>
<li>Git</li>
<li>Visual Studio Code (or your preferred editor)</li>
<li>Hugo binary</li>
</ul>
<h3 id="heading-heres-a-high-level-overview-of-our-workflow">Here's a high level overview of our workflow:</h3>
<ol>
<li>Download/Install Hugo</li>
<li>Create a Hugo project</li>
<li>Add and configure a theme</li>
<li>Add to Git</li>
<li>Deploy to Netlify</li>
<li>(Optional) Configure the free Netlify CMS</li>
</ol>
<h3 id="heading-download-or-install-hugo">Download or install Hugo</h3>
<p>To <a target="_blank" href="https://gohugo.io/getting-started/installing/">install Hugo</a>, I went over to their <a target="_blank" href="https://github.com/gohugoio/hugo/releases">GitHub Releases</a> page and downloaded their standalone Windows x64 binary. I placed it in my Projects directory, where we will be creating our site (you can always install it properly/add the binary to your PATH, but I wanted quick).</p>
<h2 id="heading-how-to-create-the-hugo-site">How to Create the Hugo Site</h2>
<p>To create a new site, simply run the below commands:</p>
<pre><code class="lang-powershell">.\hugo.exe new site hugo<span class="hljs-literal">-blog</span>
<span class="hljs-built_in">mv</span> .\hugo.exe .\hugo<span class="hljs-literal">-blog</span>
<span class="hljs-built_in">cd</span> .\hugo<span class="hljs-literal">-blog</span>
.\hugo.exe server <span class="hljs-literal">-D</span> -<span class="hljs-literal">-gc</span>
</code></pre>
<p>We now have our project created, and have just started the Hugo server. We used the <strong>-D</strong> flag to tell Hugo to show draft content, and I typically add in <strong>--gc</strong> to ensure that cleanup is run each time by clearing the cache.  </p>
<p>You can access your site at http://localhost:1313.</p>
<h3 id="heading-understanding-the-directory-structure">Understanding the directory structure</h3>
<p>You should now see the following directory structure:</p>
<pre><code class="lang-shell">|__archetypes
|__assets *this will not show up by default
|__config *this will not show up by default
|__content
|__data
|__layouts
|__static
|__themes
|__config.toml
</code></pre>
<ul>
<li><strong>archetypes</strong>: Content template files with pre-configured front matter. We won't really be touching this.</li>
<li><strong>assets</strong>: Store any files processed by <a target="_blank" href="https://gohugo.io/hugo-pipes/">Hugo Pipes</a>. This is out of scope for this tutorial.</li>
<li><strong>config</strong>: Optional directory to store configuration files. We won't be doing anything too crazy, so we will just use the default config.toml file.</li>
<li><strong>content</strong>: This is where your content lives - your posts and pages. The top level folders within this directory are treated as a <em>section</em>.</li>
<li><strong>data</strong>: Contains configuration files used by Hugo. I never had a need to touch this directory.</li>
<li><strong>layouts</strong>: Stores partial or full page HTML templates for the site. Anything in here can overwrite a corresponding entry from your theme, allowing you to customize the theme without modifying the theme's actual files.</li>
<li><strong>static</strong>: Store any static content, such as images, CSS, or scripts. Anything in this folder is copied as-is, without any modification or interpretation by Hugo. This is where you will store your media, such as images, for reference in your blog posts.</li>
<li><strong>themes</strong>: The directory where you will install any Hugo themes.</li>
<li><strong>config.toml</strong>: The default site configuration. You can use a separate directory if you want to separate different environments.</li>
</ul>
<h2 id="heading-how-to-add-your-first-theme">How to Add Your First Theme</h2>
<p>For this blog, we will use the <a target="_blank" href="https://github.com/EmielH/tale-hugo">tale</a> theme for Hugo. Run the following commands from the root of the project:</p>
<pre><code class="lang-powershell">git submodule add https://github.com/EmielH/tale<span class="hljs-literal">-hugo</span>.git .\themes\tale
</code></pre>
<p>We will <strong>NOT</strong> be editing any files from the theme, but will make all modifications in the <strong>layouts</strong> folder discussed above. This will let us always update the submodule to update our theme without worry that we will overwrite any changes we have made.</p>
<p>To initialize the theme, edit the <strong>config.toml</strong> in your root directory and add the following lines (while also editing the defaults):</p>
<pre><code class="lang-toml"><span class="hljs-comment"># Theme Settings</span>
<span class="hljs-attr">theme</span> = <span class="hljs-string">"tale"</span>
<span class="hljs-section">[params]</span>
  <span class="hljs-attr">Author</span> = <span class="hljs-string">"Aaron Katz"</span> <span class="hljs-comment"># Add the name of the author (this theme only supports one author)</span>
<span class="hljs-section">[author]</span>
  <span class="hljs-attr">name</span> = <span class="hljs-string">"Caliburn Security"</span> <span class="hljs-comment"># Used by the foot copyright</span>
</code></pre>
<p>There we go, the theme is now active! (Note that in many cases, themes will require you to copy and paste the theme's <strong>theme.toml</strong> file into your <strong>config.toml</strong>)</p>
<p>Go ahead and check out your page – every time you save a file Hugo rebuils the site live.</p>
<h3 id="heading-how-to-modify-theme-files">How to modify theme files</h3>
<p>One issue with the current theme is that non-post content will be displayed in the homepage list.  </p>
<p>To change this, let's copy the <strong>.\themes\tale\layouts\index.html</strong> page to <strong>.\layouts\index.html</strong>. </p>
<p>Once there, replace: <code>{{range (.Paginate .Site.RegularPages).Pages}}</code> with <code>{{ range where .Paginator.Pages "Section" "post" }}</code>. This will ensure only the "post" section will be displayed in the list.</p>
<p>I also wanted to add a brief footer, so go ahead and create a new file at <strong>.\layouts\footer.html</strong> and add the following code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-symbol">&amp;copy;</span> <span class="hljs-tag">&lt;<span class="hljs-name">time</span> <span class="hljs-attr">datetime</span>=<span class="hljs-string">"{{ now }}"</span>&gt;</span>{{ now.Format "2006" }}<span class="hljs-tag">&lt;/<span class="hljs-name">time</span>&gt;</span> {{ .Site.Author.name }}
    <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-add-google-analytics">How to Add Google Analytics</h3>
<p>I also wanted to add some Google Analytics to my blog, and I noticed the theme didn't incorporate this functionality.  </p>
<p>Luckily, Hugo makes adding analytics extremely simple. Open up the <strong>config.toml</strong> file and add the following line:</p>
<pre><code class="lang-toml"><span class="hljs-attr">googleAnalytics</span> = <span class="hljs-string">""</span> <span class="hljs-comment"># The UA-XXX number from Google Analytics</span>
</code></pre>
<p>Once the configuration is saved, copy the <strong>.\themes\tale\layouts\partial\head.html</strong> file to <strong>.\layouts\partial\head.html</strong> and add the following code right below the <em>head</em> tag:</p>
<pre><code class="lang-go">{{ template <span class="hljs-string">"_internal/google_analytics_async.html"</span> . }}
</code></pre>
<p>There we go, now we have Google Analytics working. Cool!</p>
<h2 id="heading-how-to-write-content">How to Write Content</h2>
<p>Let's add a nice About page so people know everything there is about me. :)</p>
<pre><code class="lang-powershell">.\hugo.exe new about.md
</code></pre>
<p>To ensure that this page is added to the main menu, add the following line to the page's front matter: <code>menu: main</code>.</p>
<p><em>Note: To build Hugo, which will generate the content under the <strong>.\public</strong> folder, simply run <code>.\hugo.exe</code></em></p>
<h3 id="heading-what-is-front-matter">What is front matter?</h3>
<p>This was a new term for me. Essentially, front matter is just structured metadata for your content. </p>
<p>By default, your template will add the following metadata fields to each page or post you create:</p>
<ul>
<li>title</li>
<li>date</li>
<li>draft</li>
</ul>
<p>Other potentially useful front matter elements are:</p>
<ul>
<li>description - This allows you to enter a description for the content.</li>
<li>expiryDate - Set a datetime for when the content should no longer be published.</li>
<li>keywords - The meta keywords for the content.</li>
<li>lastmod - The datetime for when the content was last modified (if you are using the enableGitInfo configuration command, this will be automatically set as the last time the file was mofieid in Git)</li>
<li>markup - When set to "rst", you can use reStructuredText instead of Markdown (this feature is experimental)</li>
<li>publishDate - Set a date in the future for the content to be displayed.</li>
<li>slug - The tail of the output URL. Defaults to the filename if not specified.</li>
<li>summary - The text used when providing a summary of the article. I find this useful if I don't want the first paragraph to appear in the summary, which is the typical default.</li>
<li> - Use the plural form of the taxonomy index, such as <em>tags</em> or <em>categories</em>.</li>
</ul>
<h4 id="heading-how-to-create-an-archetype-for-blog-posts">How to create an archetype for blog posts</h4>
<p>Let's go ahead and change the default front matter we see for blog posts. In the archetypes folder, create a new file called <strong>posts.md</strong> and add the following:</p>
<pre><code class="lang-yaml"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">"<span class="hljs-template-variable">{{ replace .Name "-" " " | title }}</span>"</span>
<span class="hljs-attr">date:</span> {{ <span class="hljs-string">.Date</span> }}
<span class="hljs-attr">draft:</span> <span class="hljs-literal">true</span>

<span class="hljs-attr">slug:</span> {{ <span class="hljs-string">.File.BaseFileName</span> }} <span class="hljs-comment"># Will take the filename as the slug. Feel free to change this to any format you like.  I like including this, so that I remind myself I have the option to change if I want.</span>

<span class="hljs-attr">summary:</span> <span class="hljs-string">""</span> <span class="hljs-comment"># Remove this if you want Hugo to just use the first 70 (configurable) characters of the post as the summary.</span>
<span class="hljs-attr">description:</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Lists</span>
<span class="hljs-attr">keywords:</span>
<span class="hljs-attr">tags:</span>
<span class="hljs-attr">categories:</span>
<span class="hljs-meta">---</span>
</code></pre>
<p>Now let's do one final build with <code>.\hugo.exe</code> and get ready to configure our Git repository.</p>
<h2 id="heading-how-to-configure-git">How to Configure Git</h2>
<p>Time to configure the project for Git:</p>
<pre><code class="lang-powershell">git init
git remote add origin &lt;YOUR GIT URL&gt;
git push <span class="hljs-literal">-u</span> origin master
</code></pre>
<p>Great, we now have our code stored within our repository, and we are ready for deployment!</p>
<h2 id="heading-how-to-deploy-your-blog">How to Deploy Your Blog</h2>
<p>Now that we have our site stored in Git, it's time to deploy! Almost done - I'll now show how to deploy to Netlify in under 10 minutes.</p>
<p>First, we need to create the Netlify application (feel free to create an account using any method available):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-192.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, we need to create the site and tell it where our Git repository is for our Hugo content:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-193.png" alt="Image" width="600" height="400" loading="lazy">
<em>Tell Netlify where your site is located</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-194.png" alt="Image" width="600" height="400" loading="lazy">
<em>Select the repository</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-195.png" alt="Image" width="600" height="400" loading="lazy">
<em>These can be left at the default settings</em></p>
<p>Next up, we will set up a custom domain for our site:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-196.png" alt="Image" width="600" height="400" loading="lazy">
<em>Select the custom domain option</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-197.png" alt="Image" width="600" height="400" loading="lazy">
<em>Enter your custom domain</em></p>
<p>You should now see your domain with a message saying to <strong>Check DNS configuration</strong>. Click on that, and enter the provided DNS record information into whichever service provider manages your DNS records:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-198.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-200.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-201.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example configuration within my Cloudflare account</em></p>
<p>Once complete, wait a few minutes for the DNS settings to propagate, and then select <strong>Verify DNS configuration:</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-202.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Behold, your site is now live!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-203.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example of my new blog hosted on Netlify!</em></p>
<p>Last, we should set up SSL for our site as a best practice. Netlify offers the option to use <a target="_blank" href="http://letsencrypt.org/howitworks/">Let's Encrypt</a> to automatically provision a certificate for your application. To do so, simply select <strong>Provision certificate:</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-204.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Note: It can take quite some time for the certificate to be generated, so just be patient.</em></p>
<h3 id="heading-netlify-deployment-settings">Netlify deployment settings</h3>
<p>We have one final step before we are truly ready to use Netlify. Unfortunately, the version of Hugo used by Netlify is somewhat outdated by default. However, we can fix this by creating our own configuration for Netlify to follow when deploying our site.</p>
<p>First, create a file called <code>netlify.toml</code> in the root of your repository, and then add the following configuration:</p>
<pre><code class="lang-toml"><span class="hljs-section">[build]</span>
<span class="hljs-attr">publish</span> = <span class="hljs-string">"public"</span>
<span class="hljs-attr">command</span> = <span class="hljs-string">"hugo --gc --minify"</span>

<span class="hljs-section">[context.production.environment]</span>
<span class="hljs-attr">HUGO_VERSION</span> = <span class="hljs-string">"0.74.3"</span>
<span class="hljs-attr">HUGO_ENV</span> = <span class="hljs-string">"production"</span>
<span class="hljs-attr">HUGO_ENABLEGITINFO</span> = <span class="hljs-string">"true"</span>

<span class="hljs-section">[context.split1]</span>
<span class="hljs-attr">command</span> = <span class="hljs-string">"hugo --gc --minify --enableGitInfo"</span>

<span class="hljs-section">[context.split1.environment]</span>
<span class="hljs-attr">HUGO_VERSION</span> = <span class="hljs-string">"0.74.3"</span>
<span class="hljs-attr">HUGO_ENV</span> = <span class="hljs-string">"production"</span>

<span class="hljs-section">[context.deploy-preview]</span>
<span class="hljs-attr">command</span> = <span class="hljs-string">"hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL"</span>

<span class="hljs-section">[context.deploy-preview.environment]</span>
<span class="hljs-attr">HUGO_VERSION</span> = <span class="hljs-string">"0.74.3"</span>

<span class="hljs-section">[context.branch-deploy]</span>
<span class="hljs-attr">command</span> = <span class="hljs-string">"hugo --gc --minify -b $DEPLOY_PRIME_URL"</span>

<span class="hljs-section">[context.branch-deploy.environment]</span>
<span class="hljs-attr">HUGO_VERSION</span> = <span class="hljs-string">"0.74.3"</span>

<span class="hljs-section">[context.next.environment]</span>
<span class="hljs-attr">HUGO_ENABLEGITINFO</span> = <span class="hljs-string">"true"</span>
</code></pre>
<p>All that's left to do is select <strong>Deploy site</strong> within the Netlify console, and your site is now live on a custom domain with SSL!</p>
<h2 id="heading-wrapup">Wrapup</h2>
<p>Whew! That was a lengthy blog post, but hopefully this shows how quick it is to get up and running with a "serverless" blog. Let's see what I learned :)</p>
<h3 id="heading-what-i-loved">What I loved</h3>
<ul>
<li>Super simple to build, just run <code>hugo serve</code></li>
<li>Live reload - make a change, save, and the page will reload</li>
<li>Just simple in general - I didn't need to deal with grunt, gulp, webpack, or others</li>
<li>Customizable output formats let you generate your static site, as well as a Google AMP site, JSON files, and so on.</li>
<li>FAST. Did I mention fast?</li>
<li>Can be deployed just about anywhere - whether using Netlify (my current choice), Amazon S3 &amp; Cloudfront, Heroku, GitHub Pages, and more.</li>
<li>Shortcodes are available if Markdown isn't enough</li>
<li>Continuous deployment - everything is version controlled, and deployed when I publish to the master branch</li>
<li>Allow commenting and sharing of posts</li>
</ul>
<h3 id="heading-challenges">Challenges</h3>
<ul>
<li>Hugo is sometimes too simple.  No plugins or extensions at all, etc.</li>
<li>Using Go is less intuitive and the shortcode feels messier than something like Vue</li>
<li>Not too many themes available, but I expect the library to keep growing, as there is a very active user base</li>
</ul>
<h3 id="heading-so-do-i-need-a-cms">So do I need a CMS?</h3>
<p>After all of this, I still had this question in the back of my mind.  And the answer is, "it depends".  </p>
<p>If I were to incorporate a lot of media, such as images or videos that I need to upload, it would certainly get tedious adding and organizing them all to the images folder in <strong>static</strong>. </p>
<p>At that point, I would look into a headless CMS such as Ghost, Netlify, or Sanity to manage the content, as long as I could still write my posts using Markdown.</p>
<h3 id="heading-references">References</h3>
<ul>
<li>https://medium.com/backticks-tildes/hugo101-getting-started-with-hugo-and-deploying-to-netlify-9a813fe23b94</li>
<li>https://blog.risingstack.com/static-site-generator-hugo-netlify/</li>
<li>http://cloudywithachanceofdevops.com/posts/2018/05/17/setting-up-google-analytics-on-hugo/</li>
<li>https://www.sitepoint.com/premium/books/a-beginner-s-guide-to-creating-a-static-website-with-hugo/read/1</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ An Introduction to the Akamai Content Delivery Network ]]>
                </title>
                <description>
                    <![CDATA[ By Dominic Fraser Akamai is one of the world’s leading Content Delivery Network (CDN) providers. Through the Akamai Intelligent Platform many products are offered to aid performance, availability, security, and insight generation. Other CDNs include ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/an-introduction-to-the-akamai-content-delivery-network-806aa16d8781/</link>
                <guid isPermaLink="false">66d45e40d14641365a0508a8</guid>
                
                    <category>
                        <![CDATA[ content delivery network  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 09 Jan 2019 16:46:06 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*e-5nwPzNiZtoAIKQOI7VJA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dominic Fraser</p>
<p>Akamai is one of the world’s leading Content Delivery Network (CDN) providers. Through the <a target="_blank" href="https://www.akamai.com/uk/en/solutions/intelligent-platform/">Akamai Intelligent Platform</a> many products are offered to aid performance, availability, security, and insight generation.</p>
<p>Other CDNs include Cloudflare, Fastly, MaxCDN, Incapsula, and Rackspace.</p>
<p>Here we will look at what a CDN is, then some specifics around Akamai’s implementation, including:</p>
<ul>
<li>The Akamai Intelligent Platform and Edge Servers</li>
<li>The Akamai Interface and Property Manager</li>
<li>Routing Performance</li>
<li>Caching</li>
</ul>
<h4 id="heading-what-is-a-cdn">What is a CDN?</h4>
<p>A user request for content on the public Internet may appear simple, connecting to the server holding the content (the ‘content origin’) and returning this to the user, but it is in fact very complex.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/jDQimdgZxgp-yZlV5hA6yO34Of9rEGZdMIRz" alt="Image" width="800" height="530" loading="lazy">
<em>Hidden complexity of connecting to the content origin</em></p>
<p>The connection may need to go through many Internet Service Providers (ISPs), peering points, and data centres, across competing networks, and suffer from no consistently available routes.</p>
<p>Many different device types and bandwidths may be used, from different global locations, with different content types requested.</p>
<p>This can lead to fluctuating speed and availability, security challenges, and little visibility of what is happening between the user and the content origin.</p>
<p>A CDN places more control in the hands of the content provider, and helps improve the end user experience.</p>
<p>It does this by acting as a parallel high-performance network, maintaining its own network of highly-distributed servers. By being dispersed over many physical and network locations, but optimized as one network, more control and reliability exists for user requests.</p>
<p>As a business grows, scaling to meet higher demands on the content origin also has challenges. We will also look at how CDN tools can be used to reduce load on the origin, helping not just improve performance, but also reduce cost by reducing how high the origin must be scaled.</p>
<h4 id="heading-akamai-intelligent-platform">Akamai Intelligent Platform</h4>
<p>Akamai maintains a global network of more than 240,000 ‘edge servers’. These are positioned at the ‘edge’ of the Internet, as close to end users as possible. To achieve this many edge servers are even located directly in ISPs, or in mobile data towers, to even greater reduce the latency between connecting to a user’s ISP before moving into the Akamai network.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/sKkZcR-fGy3yMTUTN8BO3uSawcmz7q6rzjK4" alt="Image" width="800" height="462" loading="lazy">
<em>Akamai network of Edge Servers</em></p>
<p>When a user makes a request, Akamai dynamically maps this to the closest available edge server. The edge server applies the business rules that the content provider has specified, before using the best available route between all other edge servers within the Akamai network to fetch content from the origin. Business rules are replicated on each edge server.</p>
<p>Any content available and configured to be cached is then cached on the edge server for future requests connecting to that node. We will look at this in more detail later on.</p>
<p>A site is added to Akamai by adding a <a target="_blank" href="https://medium.freecodecamp.org/why-cant-a-domain-s-root-be-a-cname-8cbab38e5f5c">CNAME</a> record in DNS that points from the hostname, say ‘community.akamai.com’, to an Akamai edge hostname, ‘community.akamai.com.edgekey.net’, where the Akamai controlled edge server mapping takes over to assign the best available edge server. If you ‘<a target="_blank" href="https://en.wikipedia.org/wiki/Dig_(command)">dig</a>’ a hostname and see ‘edgekey.net’ then you know Akamai is being used by the content provider.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/tGhFH9LxM9izuNJab-6YGfSDfvdwD6weLNCt" alt="Image" width="800" height="122" loading="lazy">
<em>Entering the Akamai network</em></p>
<h4 id="heading-akamai-interface">Akamai Interface</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/CFgbmCCeyAd9V9tx7PsMr00nIGHBgiHB4SE1" alt="Image" width="800" height="675" loading="lazy">
_Akamai’s [Luna Control Center](https://www.akamai.com/uk/en/solutions/intelligent-platform/control-center/" rel="noopener" target="<em>blank" title=") and Property Manager</em></p>
<p>Akamai provides a web GUI named the ‘<a target="_blank" href="https://www.akamai.com/uk/en/solutions/intelligent-platform/control-center/">Luna Control Center</a>’, several <a target="_blank" href="https://developer.akamai.com/api/">APIs</a>, and a <a target="_blank" href="https://developer.akamai.com/cli">CLI</a>.</p>
<p>As seen in the <em>Monitor</em> tab, many reporting and analytics tools are available for generating insights at a CDN level. Logs from edge servers are also available on request.</p>
<p>In the <em>Configure</em> tab we will focus on introducing Property Manager, and leave other options for a future post.</p>
<p>A <em>property</em>, sometimes also referred to as a <em>configuration</em>, is the main way to control how edge servers respond to user requests. Properties apply a list of <em>rules</em> to a set of <em>hostnames</em>, and you can only apply one property at a time to any given hostname. Rules are made up of <em>criteria/match conditions</em> and <em>behaviors</em>. An additional example of this will be seen later when looking at caching. Each property’s default rule must specify a valid <em>Content Provider</em> (<em>CP) code</em> to bill and report for the service. Rules are ‘last match wins’.</p>
<p>A Property Manager API (and <a target="_blank" href="https://developer.akamai.com/legacy/cli/packages/property-manager.html">CLI</a>) exists, with a great <a target="_blank" href="https://developer.akamai.com/api/core_features/property_manager/v1.html#papiconcepts">glossary of concepts</a>.</p>
<p>When making changes to a property a new version is first created, allowing changes to be made and tested while the previous property remains active. The new version can be first activated on the Akamai staging network, that a developer can point their local machine to run tests against, before activating in production. Production activation takes roughly ten minutes to globally roll out the new version to all edge servers, with a fast fallback option rolling back within minutes.</p>
<h4 id="heading-route-performance">Route Performance</h4>
<p>In addition to providing an ever increasing amount of distributed edge servers, to be able to serve cached content from as close to every user as possible, the route to the content origin can be optimized. In Akamai’s case this is via <a target="_blank" href="https://developer.akamai.com/legacy/learn/Optimization/SureRoute.html">SureRoute</a>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/AWcofYrlrbalUfaAe4iWIxe6IIFMHevRE4M8" alt="Image" width="800" height="340" loading="lazy">
<em>SureRoute view of possible routes to the Content Origin</em></p>
<p>Akamai’s network of servers (a user first connects to the edge server and any subsequent parent to that server) <em>overlays</em> the default route to the origin. The default route may pass between several different ISPs and networks, which may not always peer well with each other. As seen above, a lossy link (or other such degradation) may mean a non-obvious route is the best option.</p>
<p>The best route is found in two steps.</p>
<ul>
<li>First, Akamai servers continually run probes against each other, and, at a lower rate, against all Akamai customer’s origins. These are used to calculate and distribute a centralized list of <em>candidate routes</em> between each edge server/origin pairing.</li>
<li>Secondly, to narrow down these raw candidate routes to a single best option, a static <em>SureRoute test object</em> is placed by each customer at their specific origin of similar size to their average expected content. <em>Races</em> to fetch this object are periodically ran between each edge server and the origin so that a record of that with the lowest latency and/or packet loss rate can be kept up to date.</li>
</ul>
<p>This means that on every request to an edge server the fastest and most reliable route at that point in time can be used to reach the origin.</p>
<h4 id="heading-caching">Caching</h4>
<p>Caching at an edge server can greatly reduce latency for the end user.</p>
<p>As organizations scale caching can also become increasingly important to reduce load on the content origin for both better performance and to reduce costs.</p>
<p>As described in the answer given to “<a target="_blank" href="https://community.akamai.com/customers/s/question/0D50f00005RtpwrCAB/do-akamai-edge-servers-share-cached-content-or-go-to-origin?language=en_US">Do Akamai edge servers share cached content</a>”, edge servers are grouped together into network ‘regions’. If a specific edge server’s cache is not populated it will send a local request to the other edge servers in its region and if a peer has content it will serve the response before caching it itself.</p>
<p>If all local peer’s caches are empty (or stale) then the request will be forwarded to the edge’s parent server, where the same local check will take place between the parent’s peers. If no content is cached along the entire route then it will return to the origin and repopulate the cache with its response.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/cl5Mskcs5NG0c-Cc1MHTY8KrRkjLb3Fmkgv5" alt="Image" width="800" height="821" loading="lazy">
<em>Cache ID Modification behaviours</em></p>
<p>The standard cache key used is made up of the host name (domain), path and query string. This can be modified to reduce cardinality and/or give more control over cache purging. This may be by only including specific query parameters, so excluding things such as product IDs, adding the values of certain cookies, headers, or user defined variables.</p>
<p>Match conditions (if ‘<em>x</em>’ cookie exists for example) can be combined with ‘bypass cache’ behaviors to create advanced scenarios such as caching different content for users with a session, or for users in different locations.</p>
<p>A browser extension such as <a target="_blank" href="https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj">ModHeader</a> can be used to view <a target="_blank" href="https://community.akamai.com/customers/s/article/Using-Akamai-Pragma-headers-to-investigate-or-troubleshoot-Akamai-content-delivery?language=en_US">Akamai Pragma Headers</a> for investigating caching behavior locally.</p>
<h4 id="heading-final-thoughts">Final thoughts</h4>
<p>Using a CDN provides more control to content providers and tools such as those described above provide <a target="_blank" href="https://www.akamai.com/uk/en/cdn/what-are-the-benefits-of-a-cdn.jsp">benefits</a> that are increasingly important when working at scale.</p>
<p>While Akamai specific products have been discussed here, similar concepts of working at scale exist with other CDN providers.</p>
<p>Other Akamai specifics may be covered in a future post, feel free to <a target="_blank" href="https://medium.com/@dfrase">keep an eye out</a> or read up on suggested next topics such as:</p>
<ul>
<li>Security enhancements with <a target="_blank" href="https://www.akamai.com/uk/en/solutions/intelligent-platform/secure-cdn.jsp">certificate</a> <a target="_blank" href="https://developer.akamai.com/api/core_features/certificate_provisioning_system/v2.html">management</a> and Web Application Firewalls (<a target="_blank" href="https://www.akamai.com/uk/en/resources/waf.jsp">WAF</a>s)</li>
<li><a target="_blank" href="https://developer.akamai.com/image-manager">Image manager</a> for optimised image delivery</li>
<li><a target="_blank" href="https://developer.akamai.com/cloudlets">Cloudlets</a> to provide granular control outside of the Property Manage activation cycle with many types available for different use cases</li>
<li>Global Traffic Management (<a target="_blank" href="https://www.akamai.com/uk/en/products/web-performance/global-traffic-management.jsp">GTM</a>) for DNS-based load balancing</li>
<li><a target="_blank" href="https://www.akamai.com/uk/en/products/web-performance/mpulse-real-user-monitoring.jsp">mPulse</a> for utilising Real User Metrics (RUM) for performance monitoring</li>
</ul>
<p>Thanks for reading ?</p>
<p>You may also enjoy:</p>
<ul>
<li><a target="_blank" href="https://medium.com/p/807d8c4960fd?source=user_profile---------11------------------">A beginner’s guide to Amazon’s Elastic Container Service</a></li>
<li><a target="_blank" href="https://medium.freecodecamp.org/incrementally-add-flow-type-checking-react-261fee015f80">How to incrementally add Flow to an existing React app</a></li>
<li><a target="_blank" href="https://medium.freecodecamp.org/progressive-enhancement-with-css-grid-8138d4c7508c">Progressive enhancement with CSS Grid</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
