<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David Boland</title>
    <description>The latest articles on DEV Community by David Boland (@debpu06).</description>
    <link>https://dev.to/debpu06</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F65659%2Fc6ff9375-8db8-401d-8bd5-0b2b38ea1688.png</url>
      <title>DEV Community: David Boland</title>
      <link>https://dev.to/debpu06</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/debpu06"/>
    <language>en</language>
    <item>
      <title>Upgrading to Optimizely Content Cloud (CMS) 12 Offers Key First-Mover Advantages</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Thu, 17 Nov 2022 06:00:00 +0000</pubDate>
      <link>https://dev.to/debpu06/upgrading-to-optimizely-content-cloud-cms-12-offers-key-first-mover-advantages-4ad8</link>
      <guid>https://dev.to/debpu06/upgrading-to-optimizely-content-cloud-cms-12-offers-key-first-mover-advantages-4ad8</guid>
      <description>&lt;p&gt;Continuing to streamline and evolve its many digital innovation products, Optimizely has made a major change to its cornerstone content management system (CMS), inviting customers to take a leap into the future.&lt;/p&gt;

&lt;p&gt;With the latest version of its CMS tool, called Content Cloud 12, Optimizely is leaving behind the .NET Framework on which all of Episerver’s CMS releases were built before the two companies merged. To move onto Content Cloud 12, Optimizely customers will have to make a major upgrade to the newer . NET platform. Is this undertaking worth it? Based on what our Nansen team has learned from our work with Optimizely and some early implementations of Content Cloud 12 with our clients, our answer is yes.&lt;/p&gt;

&lt;p&gt;Upgrading to &lt;a href="https://www.optimizely.com/products/content/" rel="noopener noreferrer"&gt;Optimizely Content Cloud 12&lt;/a&gt; delivers a whole host of benefits, most of which spring from its use of the open-source .NET platform (formerly known as .NET Core). First introduced by Microsoft in 2014 to host apps that could run on any platform, not just Windows, .NET is cross-platform and built on a high-performance runtime.&lt;/p&gt;

&lt;p&gt;For Optimizely customers, using a CMS that runs on .NET rather than .NET Framework creates opportunities for platform consolidation, cost savings, performance improvements and enhanced talent acquisition capabilities. It also sets them up for faster time-to-innovation in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform consolidation and cost savings
&lt;/h2&gt;

&lt;p&gt;Some IT organizations rely heavily on Windows and other Microsoft products. But for the many companies that do not, the ability to run their CMS via Optimizely Content Cloud on non-Windows platforms introduces greater flexibility to their tech-stack choices, creating some immense advantages.&lt;/p&gt;

&lt;p&gt;If an Optimizely customer hosts some of their tech stack on, say, Linux or Amazon Web Services (AWS), they can now consolidate their platforms by moving the .NET-based CMS 12 off of Microsoft. This not only simplifies the running of the IT organization and tech infrastructure, it can also lead to cost savings. Microsoft and Windows are excellent products, but they are often more expensive than competitors like Linux and AWS. Cutting the cost of a Windows-hosted CMS can make a big difference in many companies’ budgets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance improvements
&lt;/h2&gt;

&lt;p&gt;One of the key tangible benefits that Optimizely CMS 12 and .NET deliver for customers is improvements in server response times and expanded request handling capabilities. &lt;a href="https://world.optimizely.com/resources/net/" rel="noopener noreferrer"&gt;According to Optimizely&lt;/a&gt;, site speed is up 4X among customers using CMS 12, and servers are handling 3X the number of requests even as performance is improving.&lt;/p&gt;

&lt;p&gt;At Nansen, we’ve seen the significant gains that can be achieved by upgrading to CMS 12 firsthand. We worked with one of our clients to make the move to .NET in May 2022. Following the deployment, this brand saw an remarkable 90% reduction in their average web transaction times.&lt;/p&gt;

&lt;p&gt;Given the indisputable impact of strong server performance on conversion rate and platform scalability, the improvements delivered by Content Cloud 12 and .NET cannot be ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talent acquisition and developer community
&lt;/h2&gt;

&lt;p&gt;As mentioned above, .NET (or .NET Core) has already been around for eight years. This means that tons of new developers have been learning on this platform for some time, in addition to the seasoned tech pros who have embraced it in addition to .NET Framework.&lt;/p&gt;

&lt;p&gt;The newer .NET platform, being open-source, also has strong community support, making it more appealing to the many developers who enjoy technical collaboration and co-creation.&lt;/p&gt;

&lt;p&gt;The war for technical talent is raging in every industry. Companies must consider the advantage they’ll gain in attracting and retaining talent by upgrading their tech stack to apps like Content Cloud 12 that use .NET.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future-proofing and decreased time-to-innovation
&lt;/h2&gt;

&lt;p&gt;We’ve mentioned several tangible and short-term benefits that upgrading to Content Cloud 12 can deliver to Optimizely customers. There are also some critical long-term factors to consider.&lt;/p&gt;

&lt;p&gt;First of all, all Optimizely CMS releases moving forward will run on .NET. Although we expect that .NET Framework and the apps that use it will continue to be supported for the foreseeable future, Optimizely customers who do not upgrade to .NET will not be able to use new versions of its powerful Content Cloud.&lt;/p&gt;

&lt;p&gt;Relatedly, with new CMS releases tend to come new, exciting features. Moving forward, most of the Optimizely Content Cloud’s latest-and-greatest features will be built for CMS 12 and .NET. Trying to retrofit these features into prior CMS versions will probably be tricky and buggy at best, and totally incompatible at worst.&lt;/p&gt;

&lt;p&gt;At Nansen, we believe in helping our clients delight today’s customers while preparing for those of tomorrow. Brands that share this mission with us should be thinking about “future-proofing” their tech stack by taking the leap to .NET apps sooner than later. This will not only save money in the long run, but will also empower customers to act quickly and embrace new innovation-focused features in the future.&lt;/p&gt;

&lt;p&gt;To learn more about Optimizely Content Cloud 12, reach out to us to &lt;a href="https://nansen.com/optimizely-demo/" rel="noopener noreferrer"&gt;schedule a demo today&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>automation</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Contentful Most Frequently Asked Questions</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Mon, 07 Feb 2022 06:00:00 +0000</pubDate>
      <link>https://dev.to/debpu06/contentful-most-frequently-asked-questions-c0p</link>
      <guid>https://dev.to/debpu06/contentful-most-frequently-asked-questions-c0p</guid>
      <description>&lt;p&gt;Working with Contentful as much as I do, I am pretty active within the community. Whether it's the Contentful's forums, their Slack community, or DMs, I come across a lot of questions.&lt;/p&gt;

&lt;p&gt;Most are specific to a given implementation. However, there are many general questions that get asked over and over. Since they keep getting asked, I figure the answers aren't the easiest to find online. This post is an effort to get those answers out there.&lt;/p&gt;

&lt;p&gt;As I come across more questions, I will continue to add to this page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Alt Tags For Images in Contentful
&lt;/h2&gt;

&lt;p&gt;To implement alt tags with Contentful images, you have two options. You can either use the existing description field, or you can create a custom model for your images.&lt;/p&gt;

&lt;p&gt;For basic implementations, using the existing description field works fine for alt text. However, if you have a more complex implementation, you may want to create a custom model. This is especially true if you need to have additional data associated with your image. There is some Contentful documentation describing &lt;a href="https://www.contentful.com/help/working-with-metadata/"&gt;adding additional metadata to an asset&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maximum Image Size in Contentful
&lt;/h2&gt;

&lt;p&gt;According to their technical specifications, the max size of an image uploaded into Contentful cannot exceed 20MB. Anything beyond 20MB will be treated as an asset.&lt;/p&gt;

&lt;p&gt;This can throw some people off, because uploading a larger image will not throw any errors. However, you will not be able to leverage any of the image manipulation tools offered by their API. So make sure you compress any images that exceed 20MB before uploading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copying Models Between Spaces in Contentful
&lt;/h2&gt;

&lt;p&gt;To move content models between spaces or environments, Contentful provides import/export functionality via their CLI.&lt;/p&gt;

&lt;p&gt;Contentful's CLI (Command Line Interface) can also migrate entire spaces and environments. This includes content models, roles, assets, content, and webhooks. You can find documentation and examples on &lt;a href="https://www.contentful.com/developers/docs/tutorials/cli/import-and-export/"&gt;Contentful's site&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Restrict Editors to Specific Content Types or Fields in Contentful
&lt;/h2&gt;

&lt;p&gt;Contentful allows for restricting editors to specific entries, content types, and fields. This can be configured in Contentful settings by navigating to Settings &amp;gt; Roles &amp;amp; Permissions &amp;gt; Edit a Role.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jEBw4UCc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.ctfassets.net/advboymm7uww/7hva92TZ0myA2EfoCJ9sgi/617983053bc8a1f2dafdc9dd5d8cba58/image__7_.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jEBw4UCc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.ctfassets.net/advboymm7uww/7hva92TZ0myA2EfoCJ9sgi/617983053bc8a1f2dafdc9dd5d8cba58/image__7_.png" alt="Contentful Roles and Permissions" width="880" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Contentful Tokens in the Client (Front End)
&lt;/h2&gt;

&lt;p&gt;Because Contentful's Content Delivery and Content Preview APIs are read only, you can use the tokens in the client without issue.&lt;/p&gt;

&lt;p&gt;You will need to use caution when using the Content Preview API token. If you have any unpublished content then it would be accessible through with this token.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preview Contentful Changes with a Static Website
&lt;/h2&gt;

&lt;p&gt;Static websites require a new build after any content changes. Because of this, you cannot immediately preview changes made in Contentful.&lt;/p&gt;

&lt;p&gt;If using a site generator such as Gatsby, you can leverage tools like incremental builds to decrease the build time. For this, you can setup a separate site that leverages the Content Preview API, as well as incremental changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error When Creating New Contentful Environment
&lt;/h2&gt;

&lt;p&gt;When creating a new environment, in order to avoid errors in your implementation, you must add your environment to any existing API keys.&lt;/p&gt;

&lt;p&gt;This can be done via Settings &amp;gt; API keys &amp;gt; then selecting your desired key. At the bottom you will see an option for Environments. Select your newly created environment to ensure it is accessible via your the API.&lt;/p&gt;

&lt;p&gt;I hope this helps! If you do have questions about an implementation, feel free to &lt;a href="https://davidboland.site/contact"&gt;reach out to me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>contentful</category>
    </item>
    <item>
      <title>How To Implement a Queue in C#</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Thu, 27 Jan 2022 06:00:00 +0000</pubDate>
      <link>https://dev.to/debpu06/how-to-implement-a-queue-in-c-3i4c</link>
      <guid>https://dev.to/debpu06/how-to-implement-a-queue-in-c-3i4c</guid>
      <description>&lt;p&gt;This post is a continuation of my series on data structures. We will be covering the queue data structure. For all of these examples of how to implement data structures, I recommend you use what's provided in your language framework when available.&lt;/p&gt;

&lt;p&gt;We will go over what it is, when you should use it, its basic operations, and the implementation.&lt;/p&gt;

&lt;p&gt;If you don't care about any of the explanation, and are only looking for code snippets, that's cool too. You can find the full implementation in my &lt;a href="https://github.com/debpu06/Data-Structures-and-Algorithms/tree/main/DataStructures/Queue"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is a Queue Data Structure?
&lt;/h2&gt;

&lt;p&gt;A Queue is a collection that keeps items in a sequence and abides by the first in, first out ( &lt;strong&gt;FIFO&lt;/strong&gt; ) rule. Regardless of when elements are inserted, the oldest element is removed first.&lt;/p&gt;

&lt;p&gt;You can visualize this by thinking of standing in line at the grocery store. The person who was first in line is the first one to checkout.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Should I Use The Queue Data Structure?
&lt;/h2&gt;

&lt;p&gt;You should use a queue data structure whenever you want to handle items in a first in, first out ( &lt;strong&gt;FIFO&lt;/strong&gt; ) order. This could be things such as incoming events and requests, or messages sent to a user.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are the Basic Operations of a Queue?
&lt;/h2&gt;

&lt;p&gt;The two main operations of a queue are &lt;strong&gt;Enqueue&lt;/strong&gt; and &lt;strong&gt;Dequeue&lt;/strong&gt;. It may contain operations for returning the queue size, an "is empty" check, and an operation for returning (but not removing) the first element.&lt;/p&gt;

&lt;p&gt;All of these operations run in &lt;em&gt;O&lt;/em&gt;(1) (constant) time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Queue Enqueue Function
&lt;/h3&gt;

&lt;p&gt;Enqueue is the insert functionality of the queue. It adds an element to the end of the collection.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;head&lt;/code&gt; node is null, we assign the newly created node to it and the tail. Otherwise, we point the "Next" reference to the newly created node. Then we set the newly created node to be the tail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QueueNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Queue Dequeue Function
&lt;/h3&gt;

&lt;p&gt;Dequeue is the remove functionality of the queue. If the queue is empty, we throw an exception.&lt;/p&gt;

&lt;p&gt;Once we confirm the queue is not empty, we store the value of the &lt;code&gt;head&lt;/code&gt; node of the queue to the &lt;code&gt;temp&lt;/code&gt; variable. We then make the second node of the queue the new "head" of the queue. Finally return the value stored in temp.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Queue Empty"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QueueNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How Do I Implementation a Queue?
&lt;/h2&gt;

&lt;p&gt;There are two different ways of implementing queues. One implementation uses an array to hold the elements, while the other uses a linked list. Each version has the operations for &lt;strong&gt;enqueue&lt;/strong&gt; and &lt;strong&gt;dequeue&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can see examples of both below. The array based version takes an "size" parameter which determines the size of the queue. The &lt;strong&gt;enqueue&lt;/strong&gt; operation for the array based implementation has an additional check to confirm the backing array has space for the new element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;queue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;//O(1)&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Queue Overflow"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;//O(1)&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Side Note: There is a way to create an array based queue that doesn't run into the size limitation issue. You would need to check on enqueue that the queue has space. If it does not, you can create a new array of larger size (usually double) and copy the elements over. This isn't the most efficient, and will have an effect on Big O complexity. But it gets the job done.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Queue Empty"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both implementations use generics so you can store any data type in the queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;As I mentioned in my article on &lt;a href="https://davidboland.site/blog/how-to-implement-a-stack-in-c"&gt;how to implement at stack&lt;/a&gt;, if you should use the queue provided with whatever framework you are using.&lt;/p&gt;

&lt;p&gt;But I hope you found this to be a helpful example of seeing how queues work under the hood. Please share your thoughts below. And feel free to share this post with others!&lt;/p&gt;

</description>
      <category>datastructures</category>
      <category>csharp</category>
    </item>
    <item>
      <title>How to Implement a Stack in C#</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Sun, 07 Nov 2021 05:00:00 +0000</pubDate>
      <link>https://dev.to/debpu06/how-to-implement-a-stack-in-c-jpe</link>
      <guid>https://dev.to/debpu06/how-to-implement-a-stack-in-c-jpe</guid>
      <description>&lt;h2&gt;
  
  
  Stacks
&lt;/h2&gt;

&lt;p&gt;This post will be a first in many going over data structures examples implemented in C#. &lt;/p&gt;

&lt;p&gt;These posts are not meant to recommend new ways of approaching old problems. More that I wanted to brush up on some of the more detailed aspects of data structures that I use every day. So many are now built into whatever framework you are using, you don't need to give any thought as to how they work.&lt;/p&gt;

&lt;p&gt;I thought a good one to start with is stacks. I will give some general info about them, then get into the actual code. &lt;/p&gt;

&lt;p&gt;If you don't care about any of the explanation, and are only looking for code snippets, that's cool too. You can find the full implementation in my &lt;a href="https://github.com/debpu06/Data-Structures-and-Algorithms/tree/main/DataStructures/Stack"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  General Info About Stacks
&lt;/h2&gt;

&lt;p&gt;Stacks are a collection that adheres to the last in, first out concept. Meaning that the most recent item added to the collection, will be the first removed. No matter how many items it contains.&lt;/p&gt;

&lt;p&gt;You can visualize this in the real world with a "stack" of books or a "stack" of plates. When you add a book to the "stack", you set it on the top. If you wanted to remove a book, you would take it from the top, or risk knocking them all over. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why Would You Use a Stack?
&lt;/h3&gt;

&lt;p&gt;You might at first think that you wouldn't have much use for stacks. In fact, people use stacks all the time.&lt;br&gt;
The back button in your browser is a good example. As you visit a web page it will add it to the stack that is your browser history. When you hit the back button, it "pops" the most recent item off the stack and redirects the user there.&lt;/p&gt;

&lt;p&gt;Another example would be tracking matching elements. For example, open and close paranthesis, open and close html tags, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  Functionality
&lt;/h3&gt;

&lt;p&gt;Stacks have a couple properties and a few functions that are pretty standard.&lt;/p&gt;

&lt;p&gt;The properties consist of variable that tracks the &lt;strong&gt;size&lt;/strong&gt; of the stack. Another that tracks the &lt;strong&gt;top&lt;/strong&gt; element.&lt;/p&gt;

&lt;p&gt;There are three main functions associated with a stack. Those are &lt;code&gt;Push&lt;/code&gt;, &lt;code&gt;Pop&lt;/code&gt;, and &lt;code&gt;IsEmpty&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Push
&lt;/h4&gt;

&lt;p&gt;Push is the insert functionality of the stack collection. It's called "Push" to symbolize pushing the item to the top of the stack. I like to think of it like those spring activated stacks of plates you see at buffets.&lt;/p&gt;

&lt;p&gt;Its return type is void and it takes as an argument the item you are adding to the stack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stack Overflow"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push runs in &lt;em&gt;O&lt;/em&gt;(1) time.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pop
&lt;/h4&gt;

&lt;p&gt;Pop is the delete functionality of the stack collection. It removes the top item from the stack and returns it. It does not take any arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;Pop&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stack Underflow"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;--;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pop runs in &lt;em&gt;O&lt;/em&gt;(1) time.&lt;/p&gt;

&lt;h4&gt;
  
  
  IsEmpty
&lt;/h4&gt;

&lt;p&gt;As the name implies, the IsEmpty function checks to see if there are any items in our stack. If there are none, it returns true. Otherwise, it returns false. &lt;/p&gt;

&lt;p&gt;This function is useful for verifying the stack has content before calling Pop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IsEmpty runs in &lt;em&gt;O&lt;/em&gt;(1) time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;In my code examples, I have two implementations of stacks. Stack.cs and NodeStack.cs. Both are stacks in the sense they function the way I describe stacks above. The difference is that Stack.cs uses an array to hold the elements, while NodeStack.cs uses a linked list. &lt;/p&gt;

&lt;p&gt;Both implementations are efficient and achieve the same goal. The difference being that Array based need to have the size of the array defined ahead of time. This can be a problem if the number of items that you push onto your stack exceeds its size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Array Stack&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IStack&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stack Overflow"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;Pop&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stack Underflow"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;--;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Side Note: There is a way to create an array based stack that doesn't run into this issue. You would need to check on push that the stack has space. If it does not, you can create a new array of larger size (usually double) and copy the elements over. This isn't the most efficient, and will have an effect on Big O complexity. But it gets the job done.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Linked List Stack&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NodeStack&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IStack&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Size&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;Pop&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stack Underflow"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;    
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;--;&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;Next&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The linked list version of the stack also has a separate class within it &lt;strong&gt;Node&lt;/strong&gt; to represent each node of the linked list.&lt;/p&gt;

&lt;p&gt;Both implementations use generics so you can store any data type in the stack. I created an IStack interface that implements the Push, Pop, and IsEmpty functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IStack&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;Pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running a quick test with both versions using strings as the types, I was get the same output shown below after pushing then popping 3 items into each.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-------------------------------------------------------------------
Test Stack (Push "Item 1", "Item 2", "Item 3")
Item 3
Item 2
Item 1
Test Node Stack (Push "Item 1", "Item 2", "Item 3")
Item 3
Item 2
Item 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full implementation can is on &lt;a href="https://github.com/debpu06/Data-Structures-and-Algorithms/"&gt;Github&lt;/a&gt;. As I go through these tutorials, I will add more to this project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;As I mentioned above, this isn't anything new. And if whatever framework you are working with provides its own implementation of a stack, use it.&lt;/p&gt;

&lt;p&gt;But if you were looking for a straightforward example of how stacks work, I hope this was helpful.as helpful.&lt;/p&gt;

</description>
      <category>datastructures</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Rendering Gatsby Images from Contentful Rich Text</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Thu, 19 Aug 2021 05:00:00 +0000</pubDate>
      <link>https://dev.to/debpu06/rendering-gatsby-images-from-contentful-rich-text-4hf5</link>
      <guid>https://dev.to/debpu06/rendering-gatsby-images-from-contentful-rich-text-4hf5</guid>
      <description>&lt;p&gt;I built this blog using Gatsby and Contentful, a combination that I love. Contentful is one of my favorite CMS to work with. And Gatsby makes building blogs so easy.&lt;/p&gt;

&lt;p&gt;When I first built the site, I had the challenge of migrating over content. For some of the pages that have images embedded in the text, I had a problem.&lt;/p&gt;

&lt;p&gt;Gatsby is great at rendering images. To do this, you need to leverage the Gatsby Image Plugin. For most of the images on the site, that is no problem. For images in Rich Text, or any references, Contentful returns custom objects.&lt;/p&gt;

&lt;p&gt;At the time I didn't think of a reasonable way to translate that to something I can pass into the Gatsby Image plugin. For Markdown, I was at least able add srcset HTML markup. Although this was super inefficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jfBZ_HF_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://images.ctfassets.net/advboymm7uww/44nT2zETgxNnqCCpFrVwa2/5dca565d65fc8a3605fd89926e03d1e5/markdown_screenshot.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jfBZ_HF_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://images.ctfassets.net/advboymm7uww/44nT2zETgxNnqCCpFrVwa2/5dca565d65fc8a3605fd89926e03d1e5/markdown_screenshot.PNG" alt="markdown screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Rich Text, I was forced to just process the asset and as a standard &lt;code&gt;img&lt;/code&gt; tag. While I had access to the fuild data for the image, I would end up using the file url data as an &lt;code&gt;img&lt;/code&gt; for the &lt;code&gt;[BLOCKS.EMBEDDED_ASSET]&lt;/code&gt; render option.&lt;/p&gt;

&lt;p&gt;While it worked to a degree, how I was rendering the image was inefficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;After my most recent Gatsby upgrade, I decided to revisit the issue.&lt;/p&gt;

&lt;p&gt;I started out by including gatsbyImageData in my GraphQL fragment for Rich Text. If you don't know what I mean by "fragment", check out the blog post I did on &lt;a href="https://davidboland.site/blog/organize-your-graphql-calls-with-fragments"&gt;organizing your GraphQL calls&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fragment RichTextBlock on ContentfulRichText {
    id
    content {
      raw
      references {
        gatsbyImageData(layout: CONSTRAINED, quality: 80, formats: [WEBP, AUTO], placeholder: BLURRED)
        contentful_id
        title
      }
    }
    sys {
      contentType {
        sys {
          id
        }
      }
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gets us all the images that are inside the rich text. The only problem is that they are all together in a single collection. There is no context as to where in the rich text they appear. So we need a way to determine where in the rich text to render them.&lt;/p&gt;

&lt;p&gt;What I ended up doing, was creating a dictionary. It's key was the Contentful Id, the value an object containing the gatsbyImageData and title. The title I leverage for alt text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;richTextImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;RichText&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;references&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reference&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;richTextImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentful_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gatsbyImageData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;documentToReactComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I stored this in a variable in my component called &lt;code&gt;richTextImages&lt;/code&gt;. I used that same variable in the options I configured for Contentful's &lt;code&gt;documentToReactComponents&lt;/code&gt;. In the option for &lt;code&gt;[BLOCKS.EMBEDDED_ASSET]&lt;/code&gt;, I had access to the Contentful Id of the asset rendering. From there, its a matter of pulling the data from the dictionary, and leveraging Gatsby Image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Bold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/b&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;align-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
​&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;richTextImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;renderMark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;MARKS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BOLD&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Bold&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Bold&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;,
&lt;/span&gt;  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;renderNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;BLOCKS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PARAGRAPH&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;,
&lt;/span&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;BLOCKS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EMBEDDED_ASSET&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// render the EMBEDDED_ASSET as you need&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imageData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;richTextImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;align-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GatsbyImage&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imageData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! I can now add images from Contentful in Rich Text with the Gatsby Image plugin.&lt;/p&gt;

&lt;p&gt;While there might be other solutions out there, this one worked for me. Since my blog posts still use Markdown, they do not leverage this fix. But you can check it out on one of my &lt;a href="https://davidboland.site/optimizely"&gt;other pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are a few items that I want to explore further. Expanding the Asset model in Contentful and storing Gatsby Image properties is one.&lt;/p&gt;

&lt;p&gt;Please let me know if you came up other options. I would love to see how others got this working.&lt;/p&gt;

&lt;p&gt;Thanks to #WOCinTech for the teaser photo used in this post!&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>contentful</category>
    </item>
    <item>
      <title>Content Modeling Custom CTAs for Contentful Web Pages</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Fri, 04 Jun 2021 02:45:39 +0000</pubDate>
      <link>https://dev.to/debpu06/content-modeling-custom-ctas-for-contentful-web-pages-4ioe</link>
      <guid>https://dev.to/debpu06/content-modeling-custom-ctas-for-contentful-web-pages-4ioe</guid>
      <description>&lt;p&gt;A common use case for Contentful is building a website. And there are lots of examples how to setup your Content Model for a website. I even did a post on &lt;a href="https://davidboland.site/blog/content-modeling-in-contentful"&gt;content modeling&lt;/a&gt; that addressed this use case.&lt;/p&gt;

&lt;p&gt;Lots of these examples contain models for everything you would expect from a website. Standard pages, articles, SEO, assets, blocks, and so on. There is one subtle aspect that can get tricky, which are CTAs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do we mean by CTAs?
&lt;/h2&gt;

&lt;p&gt;CTAs are calls to action. You run across these every day whenever you see a button that has "Buy" or "Read More" on it.&lt;/p&gt;

&lt;p&gt;They are buttons you want your site visitor to click on. They are sometimes presented along with a teaser, which is an image and text that adds some context to the CTA. This could be a product teaser that shows the price, image, and description of the product you are about to buy. In the "Read More" example, this could be an image and title of an article that you will are redirected to from the CTA.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modeling CTAs in Contentful
&lt;/h2&gt;

&lt;p&gt;From the content modelers perspective, you might go straight to a &lt;code&gt;CTA&lt;/code&gt; content type. This would consist of the microcopy for the CTA, as well as the URL that the CTA would redirect the user. While from a modeling perspective this makes sense, once you start entering content this will get messy. If you have any type of listing page (article or product), you could have hundreds or thousands of products. If you need to create a CTA entry for each one of these, you would end up with hundreds or thousands of &lt;code&gt;CTA&lt;/code&gt; entries.&lt;/p&gt;

&lt;p&gt;So what's the fix here? The cleanest way to implement a CTA would to be adding a &lt;code&gt;CTA Text&lt;/code&gt; field to the entry that is being referenced. For example, if you have a &lt;em&gt;Blog Post&lt;/em&gt; content type, you would add a short string field for &lt;code&gt;CTA Text&lt;/code&gt;. Within there you can specify "Read More" or "Continue Story" or whatever microcopy you want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WB2VUH4J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://images.ctfassets.net/advboymm7uww/dG9RnO34ZLDMma6OO07zz/cabecc0c622117a4dd5949395d126538/Blog_Post_with_CTA.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WB2VUH4J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://images.ctfassets.net/advboymm7uww/dG9RnO34ZLDMma6OO07zz/cabecc0c622117a4dd5949395d126538/Blog_Post_with_CTA.PNG" alt="Blog Post With CTA"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When building your listing, or whatever page you have the CTA, you can reference the entry of the page (&lt;em&gt;Blog Post&lt;/em&gt; in this example). When rendering, you can get both the URL and the CTA from the &lt;em&gt;Blog Post&lt;/em&gt; entry. This allows you to customize CTA text without flooding Contentful with separate entries.&lt;/p&gt;

&lt;p&gt;You might come across instances where you need CTAs for pages that are not in Contentful. Maybe it's an asset that you want to add a "Download" CTA for. Or it could be a page on a separate website. For these we would create separate content types, and make sure to include the &lt;code&gt;CTA Text&lt;/code&gt; field on them.&lt;/p&gt;

&lt;p&gt;In the asset example, that would mean a content type, call it "Downloadable Asset". It would have at least 2 fields, a &lt;code&gt;Image&lt;/code&gt; reference field to the asset in Contentful, and the &lt;code&gt;CTA Text&lt;/code&gt; field. The external URL could be the example we discussed above, where you have a Content Type that is made up of a &lt;code&gt;URL&lt;/code&gt; field and a &lt;code&gt;CTA Text&lt;/code&gt; field. The only difference being that the URL here would only point to external sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking It a Step Further
&lt;/h2&gt;

&lt;p&gt;While this works for most instances, there are always options for expanding. One way would be adding fields for teaser data. As I mentioned above, this could be relevant for &lt;em&gt;articles&lt;/em&gt; or &lt;em&gt;product&lt;/em&gt; pages. You could add a reference field to an image asset, fields for a teaser title and teaser text for the description. Wherever you reference the page entry, you'll have all the content you need to render your teaser.&lt;/p&gt;

&lt;p&gt;You could also create a &lt;em&gt;CTA Text&lt;/em&gt; content type, that can be referenced by the pages. This would be different than the CTA type that we mentioned above. Instead of containing fields for URL and Text and getting referenced on the entry where the CTA would live, we would have a field just for text. Then we can reference it on the entry the CTA points to. So similar to our "cleanest" solution above, with the exception that the CTA Text field is its own separate entry, and referenced by the Blog Post page.&lt;/p&gt;

&lt;p&gt;The benefit of this would be two fold. If you only planned to have two separate CTAs, say "Read More" and "Buy", you could create entries for those and reference them on your pages. Then, if you wanted to update the text sitewide. Say, go from "Buy" to "Purchase", you can make the change in one place and be done.&lt;/p&gt;

&lt;p&gt;Separating the CTAs to referenced entries can also create opportunities for A/B testing. You could have a multi reference field for CTAs on the &lt;em&gt;product&lt;/em&gt; page, reference a "Buy" CTA and a "Purchase" CTA. During testing, you can pull one or the other based on your criteria.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Content modeling can be tricky. For every approach to solving a problem, there are 3 others that can seem just as good depending on your use case. Finding the right approach requires understanding your editors, business uses, and technical requirements.&lt;/p&gt;

&lt;p&gt;For more info on &lt;a href="https://davidboland.site/blog/content-modeling-in-contentful"&gt;Content Modeling in Contentful&lt;/a&gt;, check out my previous post about it. And as always, if you have additional questions, please comment below or reach out on Twitter.&lt;/p&gt;

&lt;p&gt;Thanks to #WOCinTech for the teaser photo used in this post!&lt;/p&gt;

</description>
      <category>contentful</category>
    </item>
    <item>
      <title>How We Built Multiple SPAs with On-page Editing using Episerver Headless</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Tue, 06 Apr 2021 23:55:24 +0000</pubDate>
      <link>https://dev.to/debpu06/how-we-built-multiple-spas-with-on-page-editing-using-episerver-headless-10ec</link>
      <guid>https://dev.to/debpu06/how-we-built-multiple-spas-with-on-page-editing-using-episerver-headless-10ec</guid>
      <description>&lt;p&gt;Episerver has given developers the ability to access its content through it's Content Delivery API. This allows you to use Episerver as a Headless CMS, accessing all of your content as JSON via a REST API.&lt;/p&gt;

&lt;p&gt;This has been a game changer for Episerver. Not only do you get the benefits of a traditional CMS, but the ability to leverage headless capabilities means you can push your Episerver content out to multiple channels, including SPAs. If you have done any research into the Content Delivery API, you might have come across the &lt;a href="https://github.com/episerver/musicfestival-vue-template"&gt;Music Festival App&lt;/a&gt; built in VueJS.&lt;/p&gt;

&lt;p&gt;Some notable features about this application are that it's a single page application (SPA), but it also allows for on page editing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5DyK1NLw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://images.ctfassets.net/advboymm7uww/5VuG5z6LKb41364L5YnHse/22d34ffab12c3980b334b276c540eff9/edit-modal-optimized.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5DyK1NLw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://images.ctfassets.net/advboymm7uww/5VuG5z6LKb41364L5YnHse/22d34ffab12c3980b334b276c540eff9/edit-modal-optimized.gif" alt="edit-modal-optimized"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We had a need to take this even a step further. We needed to store content for multiple SPAs within the same Episerver instance, where the SPAs themselves would be hosted in a different location. While the Episerver instance also maintains an existing site. We'll get into a bit more detail about the project next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Requirements
&lt;/h2&gt;

&lt;p&gt;A client came to us describing a project for multiple portal applications that were being built by a separate part of the organization than the part that maintains their main site. This part of the organization had its own development team, and had requirements to build their portals as Angular applications hosted in Amazon AWS. They also wanted to leverage a headless CMS for editing content, but hadn't decide on which yet. While the portals would be built and maintained by separate parts of the organization, some of the content editors for both the main site and the portal applications would be the same.&lt;/p&gt;

&lt;p&gt;Because some of the content editors would need to work in both CMS, they came to us for recommendations. They knew they wanted to explore a headless option, however they didn't want to lose out on some of their favorite Episerver features like on page editing or personalization. With the requirement that we provide a headless option, and the knowledge that the editors love Episerver's features, it took us all of two seconds to come up with Episerver's Content Delivery API as a solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;On the surface, the solution was straight forward. We already demonstrated that Episerver's features could be leveraged in a headless context with the Music Festival example we mentioned above. It has personalization, on page editing, and was built out as a SPA. There are however a few differences that make this implementation different. Unlike the Music Festival example, these SPAs would not be the main site this Episerver instance is running. Second, the actual markups for these SPAs is hosted outside of Episerver. This will present some challenges around on page editing that we will discuss in more detail below.&lt;/p&gt;

&lt;h3&gt;
  
  
  CMS Content Structure
&lt;/h3&gt;

&lt;p&gt;One of those differences mentioned is that the portal applications were not the main site that Episerver is powering. Episerver has multi site capability, so that was one potential route. We decided to go for an even simpler approach, creating Containers in the Episerver page tree. Each container was assigned to a SPA. This allowed us to organize all the SPAs that would be potentially added, as well as easily control other aspects, such as permissions. It also allowed for a simplified approach when querying content from Episerver. Once a container is defined, its Id is set. With multiple development teams building out multiple portals, we can define how they all should be pulling content by putting it in the context of that container. An example being, "get all pages of type 'y', under container with id='z'".&lt;/p&gt;

&lt;p&gt;We also created custom page types that would be used for the Angular applications. Custom page types not only made for easier querying for the other developers, since all the queries could just include a parameter that specified the page type, but it also assisted in on page editing.&lt;/p&gt;

&lt;p&gt;In the razor views of our custom page types, we subscribed to specific Episerver events. One of which listened for updates to the associated properties as they were modified during on page editing. We also subscribed to a page load as well as an empty div tag that we used as reference to know where to load the associated page of the angular app.&lt;/p&gt;

&lt;h3&gt;
  
  
  On Page Editing
&lt;/h3&gt;

&lt;p&gt;The third, and more challenging difference between our application and the music festival app was on page editing. Remember that one of the requirements was that the portal applications would be hosted as separate apps in Amazon AWS? The Episerver instance is hosted with Episerver DxP in Microsoft Azure. Because Episerver cannot load an external site to render its editing interface, we would need to figure out a way to render the Angular App within Episerver.&lt;/p&gt;

&lt;p&gt;While almost every aspect of the organization was separate, one thing they did share was source control. They belonged to the same organization in Github. To incorporate the angular apps into our Episerver code base, we created git submodules.&lt;/p&gt;

&lt;p&gt;Submodules are a cool feature in git that allow you to reference another project from within an existing one. You can continued to treat them both as separate projects. Any changes to one require their own separate commits and pushes separate from the other.&lt;/p&gt;

&lt;p&gt;In this scenario, we were given read access to the Angular project repository, and setup the submodule in the Episerver repository. For our Episerver site's front end, we have a separate build process using node.&lt;/p&gt;

&lt;p&gt;As part of that build process, we added a step to get the latest from the submodule that contains the Angular app, and build it.&lt;/p&gt;

&lt;p&gt;This allowed us to have the latest version of the app available for on page editing, without any additional effort on our end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m1tSVFYL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://images.ctfassets.net/advboymm7uww/2469SZzYrm1Comma2ykWsL/3b239c1d3bcce566349f20f53eb26091/architecture.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m1tSVFYL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://images.ctfassets.net/advboymm7uww/2469SZzYrm1Comma2ykWsL/3b239c1d3bcce566349f20f53eb26091/architecture.png" alt="architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there, the developers working on the Angular app only had to make sure they include episerver editor html attributes. When you load the on page editor in Episerver, it knows what areas to wrap in the green box which can be clicked on and edited, by looking at attributes within the markup. So if there is h1 header on the page whose content is being pulled from Episerver, you only need to add a few html attributes to the h1 that specify that is represents an Episerver property, and which property it is, and you will have on page editing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Angular App
&lt;/h3&gt;

&lt;p&gt;The Angular app itself was pretty standard. As we mentioned before we needed to add attributes around elements to ensure they were picked up in Episerver for on page editing.&lt;/p&gt;

&lt;p&gt;One other aspect we had to consider was routing. To enable us to load the appropriate page in the SPA when it on page editing, we had to add custom routes to map to Episerver pages in the CMS. If you ever looked closely at the URL when on page editing, you will notice its uniform across pages, with the exception that it updates an id at the end. This is the ContentLink id of the page.&lt;/p&gt;

&lt;p&gt;Luckily, this id is returned along with the rest of the data that the Angular app pulls from Episerver's Headless API. From there we are able to assign additional routes to pages to handle when they are loaded within the CMS. That way, no additional configuration needs to be done to map pages in the Angular app to pages in the CMS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;While everything we covered checks all the boxes of our requirements, there are definitely some limitations to our implementation.&lt;/p&gt;

&lt;p&gt;The main one being maintaining consistency between environments. While we were able to grab the latest version of the Angular apps through the submodules, it would only update for the editor when we also deployed the code for the Episerver site. Because of this, we had to coordinate when properties needed to be added or modified to maintain consistency between the portal and editor experience.&lt;/p&gt;

&lt;p&gt;If any styling or layout changes were made, the understanding was that the editor experience might not match the app exactly until the next deploy, but would still allow editor so to modify content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;While this implementation might not be a common use case, I think it provides a great example of the range Episerver has as a platform. Not only was it able to continue functioning as the main site for our client, but it was able to leverage it's Content Delivery API to provide more channels for content.&lt;/p&gt;

&lt;p&gt;If you have any questions about Episerver's Content Delivery API, or any of our other implementations, feel free to &lt;a href="https://nansen.com/contact/"&gt;reach out to us&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>episerver</category>
    </item>
    <item>
      <title>Organize Your GraphQL Calls with Fragments</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Fri, 23 Oct 2020 20:33:45 +0000</pubDate>
      <link>https://dev.to/debpu06/organize-your-graphql-calls-with-fragments-419k</link>
      <guid>https://dev.to/debpu06/organize-your-graphql-calls-with-fragments-419k</guid>
      <description>&lt;p&gt;If you've worked with Gatsby, you know there are all kinds of different ways to source content. Everything from markdown files to full fledged CMS have been used. Here at Nansen, our content source of choice is Contentful. Its flexibility allows for us to quickly develop and easily scale for any Gatsby implementation.&lt;/p&gt;

&lt;p&gt;One great feature of Contentful is its flexibility when it comes to defining the content model. If you have a content type, you can easily set it up so that it can reference any other content type. This is beneficial if you want to create pages where the content can be dynamically defined in the CMS.&lt;/p&gt;

&lt;p&gt;For example, you may have a standard page content type you defined in Contentful. This standard page probably has all the properties you would expect of a web page. Title, slug (path), meta data, hero image, etc. But for the actual content of the page, you might want more flexibility. Maybe you want to add a product that renders as a teaser. Or maybe its a list of FAQs. Content like this is best defined as their own content types in Contentful and referenced, not as properties on the page itself.&lt;/p&gt;

&lt;p&gt;I wanted to take you through a couple steps we follow for our implementations. We find this to be the easiest way to develop for this kind of page content. I won't go much into the Contentful side and the content model. But if you want to learn more, I suggest you check out our earlier post on &lt;a href="/blog/content-modeling-in-contentful"&gt;Content Modeling in Contentful&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query Contentful
&lt;/h2&gt;

&lt;p&gt;In Gatsby, the standard way of making calls for content is by using GraphQL. If we keep using the standard page example, you will have built out a template in code for the standard page. In our examples we'll call it standard-page.js. This template would be referenced from your gatsby-node.js file, where you do your initial Contentful query for all the Standard Page content types, getting some initial info like content id, slug, etc. &lt;/p&gt;

&lt;p&gt;On the standard-page.js template itself, you need to make a call for the rest of the content for that specific page. Below, we are getting content for the "About us" page specifically.&lt;/p&gt;

&lt;p&gt;Your first instinct might be to build your call like the following, where you specify all your properties, as well as any referenced content. You are also probably using the &lt;a href="https://graphql.org/learn/queries/#inline-fragments" rel="noopener"&gt;inline fragments&lt;/a&gt; for querying your Contentful content :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nx"&gt;MyQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;contentfulStandardPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;about-us&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;
    &lt;span class="nx"&gt;blocks&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;ContentfulHeroBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;id&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt;
        &lt;span class="nx"&gt;title&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;fluid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;src&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;ContentfulTextBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;id&lt;/span&gt;
        &lt;span class="nx"&gt;bodyContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;bodyContent&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This unfortunately will not work for us. The way Gatsby/GraphQL work together is that a schema is built during the build, which tells us what content will be available to query for the &lt;strong&gt;Standard Page&lt;/strong&gt;. If our &lt;strong&gt;Standard Page&lt;/strong&gt; will always reference the &lt;strong&gt;HeroBlock&lt;/strong&gt; content type as well as the &lt;strong&gt;TextBlock&lt;/strong&gt; content type, then we are fine.&lt;/p&gt;

&lt;p&gt;However, if we ever remove the reference to the &lt;strong&gt;HeroBlock&lt;/strong&gt; in Contentful, our code will break. This is because Gatsby/GraphQL creates a schema from Contentful based on the content types that are set in your &lt;strong&gt;Standard Page&lt;/strong&gt; at the time the static pages are generated. So if you just add your call for the &lt;strong&gt;HeroBlock&lt;/strong&gt;, and there is no &lt;strong&gt;HeroBlock&lt;/strong&gt; referenced by a &lt;strong&gt;Standard Page&lt;/strong&gt; in Contentful at the time, the build will break.&lt;/p&gt;

&lt;p&gt;If we need to update code as we update the content model, that's one thing. But we don't want to be in a situation where we need to update code as we update content. So we need to come up with a better way.&lt;/p&gt;

&lt;p&gt;Luckily there is one. The solution we came up with is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nx"&gt;MyQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;contentfulStandardPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;about-us&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;
    &lt;span class="nx"&gt;blocks&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;__typename&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;ContentfulHeroBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;id&lt;/span&gt;
          &lt;span class="nx"&gt;name&lt;/span&gt;
          &lt;span class="nx"&gt;title&lt;/span&gt;
          &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;fluid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;src&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;ContentfulTextBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;id&lt;/span&gt;
          &lt;span class="nx"&gt;bodyContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;bodyContent&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line to call out here is the on Node portion. If you want the content in Contentful to be truly dynamic, you need this to your call. Node just indicates you want an object with an Id, regardless of the type. Now your call will pass regardless of what content types are referenced on your &lt;strong&gt;Standard Page&lt;/strong&gt;, because all possible references are considered a Node type.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Rendering with React Components
&lt;/h2&gt;

&lt;p&gt;Assuming you have different React components to represent these different content types, your first thought might be to implement either a switch statement or multiple if/else's to determine which component to use based on the GraphQL query results. &lt;/p&gt;

&lt;p&gt;But after you sit with it for a minute, you'll probably come to the same conclusion we did. Which is that the if/switch statement approach doesn't scale. Instead, we built a component to manage a collection of content called a "ContentArea" component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContentArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;contentTypes&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentTypes&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;contentTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DynamicComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ComponentList&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DynamicComponent&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DynamicComponent&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ContentArea&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how we reference the ContentArea component from our standard-page.js template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ContentArea contentTypes={page.blocks} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We pass in all our page content, the ContentArea component loops through each item, and checks it against a dictionary we call ComponentList to determine which component to use. Going forward, every time you add a new content type that can be referenced on the Standard Page, you can add it to your ComponentList dictionary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heroBlock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;textBlock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TextBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fiftyFifty&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FiftyFifty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ContentfulImage&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you have it! The dynamic power of Contentful in Gatsby.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;If you haven't already, next I would recommend looking into creating Fragments. Because you might be making similar GraphQL calls from other content types, its good to separate out that logic to avoid repeated code. This will ensure your code continues to be dynamic and scalable. You can check out a few examples of Fragments I made as &lt;a href="https://gist.github.com/debpu06" rel="noopener"&gt;gists&lt;/a&gt; in Github.&lt;/p&gt;

&lt;p&gt;As always, feel free to reach out to me or our team if you have any questions.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>gatsby</category>
    </item>
    <item>
      <title>Image Gallery Powered By Contentful</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Fri, 23 Oct 2020 20:01:36 +0000</pubDate>
      <link>https://dev.to/debpu06/image-gallery-powered-by-contentful-48ip</link>
      <guid>https://dev.to/debpu06/image-gallery-powered-by-contentful-48ip</guid>
      <description>&lt;p&gt;If you've worked with Contentful before, you are probably familiar with the power of their Images API. If you haven't, it's worth checking out.&lt;/p&gt;

&lt;p&gt;While Contentful itself has a lot of great features, how it manages images is one of the coolest. First of all, all images (up to a certain size) are compressed once they are uploaded to Contentful. Secondly, like all the other content on Contentful, it leverages its content delivery network (CDN) for quick access. Third, accessing those images via their API provides lots of features. Some of those include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specifying Image Format&lt;/li&gt;
&lt;li&gt;Resizing and Cropping&lt;/li&gt;
&lt;li&gt;Changing Quality&lt;/li&gt;
&lt;li&gt;Specifying Focus Areas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these can be done on a per request. Not only that, once you make that request, the updated image is stored in their CDN for future requests. &lt;/p&gt;

&lt;p&gt;Leveraging all these features can help you create a really awesome image gallery. We did just that for the &lt;a href="https://uspoloassnglobal.com/collections/spring-2020" title="U.S. Polo Gallery Link" rel="noreferrer"&gt;U.S. Polo Association&lt;/a&gt;, and we wanted to share some of the features we leveraged from Contentful to do it. You can checkout the full implementation in &lt;a href="https://gist.github.com/debpu06/8398e588d34409fd241a7e9ad4742e44" title="github gist" rel="noreferrer"&gt;gallery.js&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;The first section of our code is the setup. We grab the container element for rendering our gallery, we grab all image URLs that we added to the page in .Collection-item, and we get the resolution of the device the gallery will be rendering on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;galleryContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;galleryItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;galleryContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.Collection-item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devicePixelRatio&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we build the call to Contentful's Images API. Here we need to do some basic calculations. Based on the resolution we got above, we calculate the needed height and width of the image. First, detect the size of each grid cell as rendered on the client side browser. Then, we multiply the height and width of each cell by the users resolution. By specifying the exact size required for each image, we maximize our performance by avoiding loading any unnecessarily large images.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lazyImage&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;imageWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offsetWidth&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;imageHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offsetHeight&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;imagePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?fit=fill&amp;amp;w=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;imageWidth&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;h=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;imageHeight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;f=faces&amp;amp;q=75`&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;imageAlt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;galleryImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;img&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We add this to the URL using the w &amp;amp; h query string parameters. We also add one for q, which specifies the quality. We put this at 75, meaning we want the image at 75% of its original quality. This could vary depending on implementation, but the images we worked with for U.S. Polo were all very high quality. So we were able to request a lower quality image without it affecting the end result.&lt;/p&gt;

&lt;p&gt;One thing you will notice for our query is that we also added f=faces. This is leveraging the "Specifying Focus Area" feature I mentioned above. When you add this, the Images API will use machine learning to focus on any faces it detects in the image. This is perfect for our situation where we are leveraging images that all feature people in them.&lt;/p&gt;

&lt;p&gt;The last feature to call out is how we update our gallery as the screen size changes.&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Reinit the photos when the media query changes from/to mobile, tablet, desktop.&lt;/span&gt;
&lt;span class="c1"&gt;// BREAKPOINT.MEDIUM.MIN === 769&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`(min-width: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BREAKPOINT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MEDIUM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px)`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-ondemand="gallery"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// BREAKPOINT.LARGE.MIN === 1440&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`(min-width: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BREAKPOINT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LARGE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px)`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-ondemand="gallery"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because our images are lazy-loaded, the screen size may change before the user gets to a point on the page where all images are loaded. If that's the case, we will want to update the image requests to work with the new screen size. This will re-call our gallery code, and make the API calls with the updated height and width.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;And that's it! It's pretty basic, but that's just a testament to the functionality of Contentful's Images API. Whether you're new to Contentful or a seasoned veteran, I hope you found this tutorial interesting. &lt;/p&gt;

&lt;p&gt;And I hope you check out our implementation on &lt;a href="https://uspoloassnglobal.com/collections/spring-2020" title="U.S. Polo Gallery" rel="noreferrer"&gt;U.S. Polo Association&lt;/a&gt;. If you have any questions regarding the &lt;a href="https://gist.github.com/debpu06/8398e588d34409fd241a7e9ad4742e44" title="github gist link" rel="noreferrer"&gt;gallery.js code&lt;/a&gt;, or questions about Contentful in general, feel free to reach out to us on &lt;a href="https://twitter.com/thisisnansen" title="github gist link" rel="noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>contentful</category>
    </item>
    <item>
      <title>Content Modeling in Contentful</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Fri, 23 Oct 2020 19:04:15 +0000</pubDate>
      <link>https://dev.to/debpu06/content-modeling-in-contentful-47oh</link>
      <guid>https://dev.to/debpu06/content-modeling-in-contentful-47oh</guid>
      <description>&lt;p&gt;Content modeling can be a tricky thing. If done incorrectly, it can cause all kinds of headaches for editors. And trust me when I say going back to update the structure of your content after your project is live is worse. It's something you want to get right the first time.&lt;/p&gt;

&lt;p&gt;Here at Nansen, we've been in the content management business a while. We thought it would be good to share some tips around content modeling in Contentful. If you aren't familiar with Contentful, I recommend checking it out. It's a headless content management system(CMS) that we've used in several implementations. If you are thinking about going headless, it should be your first look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;p&gt;Before you dive in, it's important to get in the "headless" mindset. If you've worked with CMS before, you might be familiar with things like pages and blocks. You may have set up your page navigation with a page tree interface. Everything gets tied to the context of a website.&lt;/p&gt;

&lt;p&gt;In Contentful, you want to separate your content from context. This doesn't mean you can't build the page, or other content types that help you define elements of a website. But you need to be able to know when to decouple elements from that context. &lt;/p&gt;

&lt;p&gt;Let's look at an example.&lt;/p&gt;

&lt;p&gt;Let's say you are in the retail space. You are looking to rebuild your website. You also installed some digital in-store displays at your brick and mortar locations.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/advboymm7uww/7nUl5I945o69z83JvAceIW/63b864db81f63a337a51d6107694d245/in-store-expereinece-3.png?w=1180&amp;amp;q=80" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/advboymm7uww/7nUl5I945o69z83JvAceIW/63b864db81f63a337a51d6107694d245/in-store-expereinece-3.png?w=1180&amp;amp;q=80" alt="two individuals looking at an in store display with an app on their phone"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You want to use Contentful to manage the content for both.&lt;/p&gt;

&lt;p&gt;Luckily, this kind of situation is exactly what Contentful was designed for. Both your site and in-store display will share a lot of the same information. Product name, sizes, colors, etc. This Product can be our first content type. It can be pulled in by our in-store display.&lt;/p&gt;

&lt;p&gt;&lt;a href="////images.ctfassets.net/advboymm7uww/6WqjdNUhzg0Jgblzdf3wdV/0fe05bcbbfec607231518642105395c8/product-content-type.png?w=1180&amp;amp;q=80"&gt;Screenshot of Contentful admin panel that shows the fields of a product content type&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;While we will still need this information on the product detail page of our website, we also need a bit more. We will need SEO data, additional page copy, maybe some references to related products. This is where the Page content type comes in.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/advboymm7uww/7aV2tnad7gkrPGPes9WWEF/ec95f39207181a0f31c04743a9b01b6a/page-content-type.png?w=1180&amp;amp;q=80" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/advboymm7uww/7aV2tnad7gkrPGPes9WWEF/ec95f39207181a0f31c04743a9b01b6a/page-content-type.png?w=1180&amp;amp;q=80" alt="Screenshot of Contentful admin panel that shows the fields of a page content type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives us everything we need. Content for our in-store display. Content for our site. And most importantly, the context and content are separated. This will help future proof our content model. We can both scale our content, or add new contexts for consuming your content. Both without effecting your existing store display or website. &lt;/p&gt;

&lt;p&gt;Sound good? Now let's cover some of our content modeling tips.&lt;/p&gt;

&lt;h2&gt;
  
  
  Include Everyone in the Discussion
&lt;/h2&gt;

&lt;p&gt;The job of content modeling isn't on any one project stakeholder. It's on the team as a whole. From the developers to the business team, and everyone in-between. The developers can call out what's possible from a development perspective.&lt;/p&gt;

&lt;p&gt;They can also usually communicate what the end result will be like for the editors. The business end will help you work out the best way to model your content to align with business goals.&lt;/p&gt;

&lt;p&gt;Brainstorming is helpful. Here are some photos of some whiteboarding we did as a team for one of our implementations.&lt;/p&gt;

&lt;p&gt;By the end, you should all be in agreement on the expected project outcome.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/advboymm7uww/3uKR5IB7wofuGCswbsCR0C/26ce0c44e59d130279d42a58786b411e/page-properties-content-modeling.jpg?w=1180&amp;amp;q=80" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/advboymm7uww/3uKR5IB7wofuGCswbsCR0C/26ce0c44e59d130279d42a58786b411e/page-properties-content-modeling.jpg?w=1180&amp;amp;q=80" alt="photo of whiteboard with post-it notes that have page properties"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/advboymm7uww/3rEaa1nKEYQnh9sIR9kWFF/099b8539a0015dc5d16efbeba8a9084d/article-listing-content-modeling.jpg?w=1180&amp;amp;q=80" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/advboymm7uww/3rEaa1nKEYQnh9sIR9kWFF/099b8539a0015dc5d16efbeba8a9084d/article-listing-content-modeling.jpg?w=1180&amp;amp;q=80" alt="photo of whiteboard with post-it notes showing the layout of a blog listing page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Leverage Content Hierarchy
&lt;/h2&gt;

&lt;p&gt;The context of your content may include some sort of navigation. For example, if you are using a website, pages might have subpages. If you have a mobile app, you may need to take the users through a multi-step process. This structure can be represented in your content modeling.&lt;/p&gt;

&lt;p&gt;A common example would be a blog listing page. You can think of your start page as the root with a path of mysite.com/. The blog listing page would then be a sub-page of the start page at mysite.com/blog/. Each blog post would be one more level down at mysite.com/blog/blogpost1.&lt;/p&gt;

&lt;p&gt;The diagram below helps visualize this.&lt;/p&gt;

&lt;p&gt;In Contentful, you can represent this structure with what's called "Top-Down Hierarchy". If you have a Page content type, it can have a reference to one (or many) other instances of Page type content items.&lt;/p&gt;

&lt;p&gt;This top-down referencing structure can reflect the same page tree structure you see in a standard CMS.&lt;/p&gt;

&lt;p&gt;This allows you to define a relationship between content, without limiting your content model to a specific context.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/advboymm7uww/SBSf2mtnIsWmQdvTHiF3G/666ea0ba913ede63b2ad83c7a57a25e3/content-page-tree-example.png?w=1180&amp;amp;q=80" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/advboymm7uww/SBSf2mtnIsWmQdvTHiF3G/666ea0ba913ede63b2ad83c7a57a25e3/content-page-tree-example.png?w=1180&amp;amp;q=80" alt="Model of a page tree of content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid Deep Nesting
&lt;/h2&gt;

&lt;p&gt;In the product detail page example above, we had an instance of page content reference an instance of product content. This idea of content referencing other content is called nesting. In all the examples we have gone through so far, we leveraged nesting.&lt;/p&gt;

&lt;p&gt;While nesting is a necessary feature, if taken too far it can be confusing for editors. Contentful recommends not nesting more than 4 to 5 levels. We would say that's should be considered the max.&lt;/p&gt;

&lt;p&gt;If you can avoid going more than 3 levels, that is ideal. Over 3 levels, it's easy for editors to lose context. Meaning if editors are editing content for a website, after 3 levels they might see properties that they know they need to edit. However, they might not understand how those properties apply to the website.&lt;/p&gt;

&lt;p&gt;This model gives an example of how quickly you can lose context the more levels you nest.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/advboymm7uww/2N2PfWHQhxYqSlArHyRrGM/2be65a4f6f19e67376c5b2670a8d58d5/content-nesting-example.png?w=1180&amp;amp;q=80" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/advboymm7uww/2N2PfWHQhxYqSlArHyRrGM/2be65a4f6f19e67376c5b2670a8d58d5/content-nesting-example.png?w=1180&amp;amp;q=80" alt="diagram that shows a tree of Contentful content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While Banner Callout content might not reference all the possible CTAs and links, it still in theory could. So it makes sense that it can get confusing for an editor.&lt;/p&gt;

&lt;p&gt;As the number of references grows, so will the complexity. If an editor is working on content for the Blue Button CTA, they may forget if it's being edited for Page Teaser or the Banner Callout. They might even forget which page they are on.&lt;/p&gt;

&lt;p&gt;Use Flexible Assemblies&lt;br&gt;
Contentful refers to content types that can reference other content types as assemblies. If your content type allows for a single reference, it's considered a fixed assembly. If it can have multiple references, its referred to as a flexible assembly.&lt;/p&gt;

&lt;p&gt;When in doubt, always opt for a flexible assembly model. We have come across instances where content modelers use fixed assemblies, or even topics (content types that don't have any references). The idea being that if you have a blog page type, it will only need the basic page data, as well as a rich text editor for the post.&lt;/p&gt;

&lt;p&gt;The problem with that approach is that requirements are always changing. Take the blog page scenario. The requirement might start out with a blog page. But what happens if you want to show teasers to related articles? Or if your post discusses a new product? You might want to reference it on the page. It's better to make these types of flexible assemblies from the start.     &lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;These tips are what we look to first when starting to build out our content models. Do we stick to them always? No. Every project is unique, with its own set of requirements.&lt;/p&gt;

&lt;p&gt;The most important thing is to work on that headless mindset. Once you have that down, knowing which of these tips best applies to your project will become easy.&lt;/p&gt;

&lt;p&gt;Are you a Contentful content modeler? Contact us via Twitter and/or Linkedin with some of your favorite content modeling tips.&lt;/p&gt;

</description>
      <category>contentful</category>
    </item>
    <item>
      <title>Dynamic Content Types with Gatsby &amp; Contentful</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Wed, 09 Sep 2020 05:00:00 +0000</pubDate>
      <link>https://dev.to/debpu06/dynamic-content-types-with-gatsby-contentful-je9</link>
      <guid>https://dev.to/debpu06/dynamic-content-types-with-gatsby-contentful-je9</guid>
      <description>&lt;p&gt;If you've worked with Gatsby, you know there are all kinds of different ways to source content. Everything from markdown files to full fledged CMS have been used. Here at Nansen, our content source of choice is Contentful. Its flexibility allows for us to quickly develop and easily scale for any Gatsby implementation.&lt;/p&gt;

&lt;p&gt;One great feature of Contentful is its flexibility when it comes to defining the content model. If you have a content type, you can easily set it up so that it can reference any other content type. This is beneficial if you want to create pages where the content can be dynamically defined in the CMS.&lt;/p&gt;

&lt;p&gt;For example, you may have a standard page content type you defined in Contentful. This standard page probably has all the properties you would expect of a web page. Title, slug (path), meta data, hero image, etc. But for the actual content of the page, you might want more flexibility. Maybe you want to add a product that renders as a teaser. Or maybe its a list of FAQs. Content like this is best defined as their own content types in Contentful and referenced, not as properties on the page itself.&lt;/p&gt;

&lt;p&gt;I wanted to take you through a couple steps we follow for our implementations. We find this to be the easiest way to develop for this kind of page content. I won't go much into the Contentful side and the content model. But if you want to learn more, I suggest you check out our earlier post on &lt;a href="/blog/content-modeling-in-contentful"&gt;Content Modeling in Contentful&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query Contentful
&lt;/h2&gt;

&lt;p&gt;In Gatsby, the standard way of making calls for content is by using GraphQL. If we keep using the standard page example, you will have built out a template in code for the standard page. In our examples we'll call it standard-page.js. This template would be referenced from your gatsby-node.js file, where you do your initial Contentful query for all the Standard Page content types, getting some initial info like content id, slug, etc. &lt;/p&gt;

&lt;p&gt;On the standard-page.js template itself, you need to make a call for the rest of the content for that specific page. Below, we are getting content for the "About us" page specifically.&lt;/p&gt;

&lt;p&gt;Your first instinct might be to build your call like the following, where you specify all your properties, as well as any referenced content. You are also probably using the &lt;a href="https://graphql.org/learn/queries/#inline-fragments" rel="noopener"&gt;inline fragments&lt;/a&gt; for querying your Contentful content :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nx"&gt;MyQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;contentfulStandardPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;about-us&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;
    &lt;span class="nx"&gt;blocks&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;ContentfulHeroBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;id&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt;
        &lt;span class="nx"&gt;title&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;fluid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;src&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;ContentfulTextBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;id&lt;/span&gt;
        &lt;span class="nx"&gt;bodyContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;bodyContent&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This unfortunately will not work for us. The way Gatsby/GraphQL work together is that a schema is built during the build, which tells us what content will be available to query for the &lt;strong&gt;Standard Page&lt;/strong&gt;. If our &lt;strong&gt;Standard Page&lt;/strong&gt; will always reference the &lt;strong&gt;HeroBlock&lt;/strong&gt; content type as well as the &lt;strong&gt;TextBlock&lt;/strong&gt; content type, then we are fine.&lt;/p&gt;

&lt;p&gt;However, if we ever remove the reference to the &lt;strong&gt;HeroBlock&lt;/strong&gt; in Contentful, our code will break. This is because Gatsby/GraphQL creates a schema from Contentful based on the content types that are set in your &lt;strong&gt;Standard Page&lt;/strong&gt; at the time the static pages are generated. So if you just add your call for the &lt;strong&gt;HeroBlock&lt;/strong&gt;, and there is no &lt;strong&gt;HeroBlock&lt;/strong&gt; referenced by a &lt;strong&gt;Standard Page&lt;/strong&gt; in Contentful at the time, the build will break.&lt;/p&gt;

&lt;p&gt;If we need to update code as we update the content model, that's one thing. But we don't want to be in a situation where we need to update code as we update content. So we need to come up with a better way.&lt;/p&gt;

&lt;p&gt;Luckily there is one. The solution we came up with is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nx"&gt;MyQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;contentfulStandardPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;about-us&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;
    &lt;span class="nx"&gt;blocks&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;__typename&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;ContentfulHeroBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;id&lt;/span&gt;
          &lt;span class="nx"&gt;name&lt;/span&gt;
          &lt;span class="nx"&gt;title&lt;/span&gt;
          &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;fluid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;src&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;ContentfulTextBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;id&lt;/span&gt;
          &lt;span class="nx"&gt;bodyContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;bodyContent&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line to call out here is the on Node portion. If you want the content in Contentful to be truly dynamic, you need this to your call. Node just indicates you want an object with an Id, regardless of the type. Now your call will pass regardless of what content types are referenced on your &lt;strong&gt;Standard Page&lt;/strong&gt;, because all possible references are considered a Node type.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Rendering with React Components
&lt;/h2&gt;

&lt;p&gt;Assuming you have different React components to represent these different content types, your first thought might be to implement either a switch statement or multiple if/else's to determine which component to use based on the GraphQL query results. &lt;/p&gt;

&lt;p&gt;But after you sit with it for a minute, you'll probably come to the same conclusion we did. Which is that the if/switch statement approach doesn't scale. Instead, we built a component to manage a collection of content called a "ContentArea" component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContentArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;contentTypes&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentTypes&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;contentTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DynamicComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ComponentList&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DynamicComponent&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DynamicComponent&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ContentArea&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how we reference the ContentArea component from our standard-page.js template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ContentArea contentTypes={page.blocks} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We pass in all our page content, the ContentArea component loops through each item, and checks it against a dictionary we call ComponentList to determine which component to use. Going forward, every time you add a new content type that can be referenced on the Standard Page, you can add it to your ComponentList dictionary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heroBlock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;textBlock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TextBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fiftyFifty&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FiftyFifty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ContentfulImage&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you have it! The dynamic power of Contentful in Gatsby.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;If you haven't already, next I would recommend looking into creating Fragments. Because you might be making similar GraphQL calls from other content types, its good to separate out that logic to avoid repeated code. This will ensure your code continues to be dynamic and scalable. You can check out a few examples of Fragments I made as &lt;a href="https://gist.github.com/debpu06" rel="noopener"&gt;gists&lt;/a&gt; in Github.&lt;/p&gt;

&lt;p&gt;As always, feel free to reach out to me or our team if you have any questions.&lt;/p&gt;

</description>
      <category>contentful</category>
      <category>gatsby</category>
    </item>
    <item>
      <title>Signing Your Work as a Developer</title>
      <dc:creator>David Boland</dc:creator>
      <pubDate>Thu, 05 Dec 2019 00:51:06 +0000</pubDate>
      <link>https://dev.to/debpu06/signing-your-work-as-a-developer-5d58</link>
      <guid>https://dev.to/debpu06/signing-your-work-as-a-developer-5d58</guid>
      <description>&lt;p&gt;In the last post, I built a contact us form using PGP encryption. I wanted to follow up with another cool encryption feature, signing. I will be walking through how you can sign your git commits. As well as any files/packages you build. &lt;/p&gt;

&lt;p&gt;Signing is a form of encryption authentication. When encrypting a message in PGP, you are able to sign it with your private key. The recipient could then verify that signature with your public key. This would allow them to verify the message was in fact sent by you. &lt;/p&gt;

&lt;p&gt;This concept of signing applies to more than messaging. Even more than encryption itself. I wanted to give some examples of how you could start signing your work as a developer. This signing doesn't involve any encryption. It serves to allow others to verify items that you have signed as yours. &lt;/p&gt;

&lt;p&gt;This post assumes you have gpg installed. &lt;/p&gt;

&lt;h2&gt;
  
  
  Key Management
&lt;/h2&gt;

&lt;p&gt;To begin signing, you will need public and private keys. The private key would be for you to sign with. The public key can be used to verify that signature. &lt;/p&gt;

&lt;h3&gt;
  
  
  Generate Key
&lt;/h3&gt;

&lt;p&gt;The first step will be generating your PGP key. Run the following command to generate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--gen-key&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will ask you to provide your name, email, and a password. It will spit out information about your newly generated key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pub rsa2048 2019-12-04 &lt;span class="o"&gt;[&lt;/span&gt;SC] &lt;span class="o"&gt;[&lt;/span&gt;expires: 2021-12-03] 
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
uid David Boland &amp;lt;david.boland@protonmail.com&amp;gt;
sub rsa2048 2019-12-04 &lt;span class="o"&gt;[&lt;/span&gt;E] &lt;span class="o"&gt;[&lt;/span&gt;expires: 2021-12-03]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will need reference to your key going forward. To get the Id, run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--list-secret-keys&lt;/span&gt; &lt;span class="nt"&gt;--keyid-format&lt;/span&gt; LONG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will spit out your keys as before, but in the specified key format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sec rsa2048/DFD20A3D39A1913 2019-12-04 &lt;span class="o"&gt;[&lt;/span&gt;SC] &lt;span class="o"&gt;[&lt;/span&gt;expires: 2021-12-03]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid &lt;span class="o"&gt;[&lt;/span&gt;ultimate] David Boland &amp;lt;david.boland@protonmail.com&amp;gt;
ssb rsa2048/XXXXXXXXXXXXXXXX 2019-12-04 &lt;span class="o"&gt;[&lt;/span&gt;E] &lt;span class="o"&gt;[&lt;/span&gt;expires: 2021-12-03]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The data after "rsa2048/" in the sec section is the user Id for that key. So in our case &lt;code&gt;DFD20A3D39A1913&lt;/code&gt;. I will use it as an example going forward. But you would use your key Id.&lt;/p&gt;

&lt;h3&gt;
  
  
  Export Key
&lt;/h3&gt;

&lt;p&gt;To verify signatures, people will need access to your public key. To export it from gpg, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--armor&lt;/span&gt; &lt;span class="nt"&gt;--export&lt;/span&gt; DFD20A3D39A1913
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your key will start with &lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----&lt;/code&gt; and end with &lt;code&gt;-----END PGP PUBLIC KEY BLOCK-----&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Signing Commits
&lt;/h2&gt;

&lt;p&gt;To sign your commits, you need to configure git locally on your machine. You also need to provide Github with your public key so that they can verify the signature on the commits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring Git
&lt;/h3&gt;

&lt;p&gt;In order to sign your commits, there are a couple configuration updates that need to be made in git. First, is specifying your key that was created previously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.signingkey DFD20A3D39A1913
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the 'global' flag makes this setting global for the specified user. &lt;/p&gt;

&lt;p&gt;Next you may need to specify to git the instance of gpg that you are using. After setting up I got the following error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg: skipped &lt;span class="s2"&gt;"name &amp;lt;name&amp;gt;"&lt;/span&gt;: secret key not available
gpg: signing failed: secret key not available
error: gpg failed to sign the data
fatal: failed to write commit object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get this error if you do not specify the &lt;code&gt;user.signingkey&lt;/code&gt;. You will also get this if you have multiple GPG instances and git looks to the wrong one. &lt;/p&gt;

&lt;p&gt;In my case I am using a console emulator, which ships with its own instance of gpg. So I needed to specify the path to my GPG instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; gpg.program gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you can sign your commits. When committing, you just need to add the &lt;code&gt;-S&lt;/code&gt; flag. &lt;/p&gt;

&lt;p&gt;You are able set up automatic signing without having to specify the flag. You can globally set the &lt;code&gt;commit.gpgsign&lt;/code&gt; setting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; commit.gpgsign &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuring Github
&lt;/h3&gt;

&lt;p&gt;In Github, navigate to your settings and there is an option for &lt;em&gt;SSH and GPG keys&lt;/em&gt;. Your keys will be listed here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AvvtokM3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://photos.davidboland.site/debpu06-blog-container/3e4e7f9c-76bc-4765-abfd-97471ed68b2e-gpg-keys-github-min.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AvvtokM3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://photos.davidboland.site/debpu06-blog-container/3e4e7f9c-76bc-4765-abfd-97471ed68b2e-gpg-keys-github-min.png" alt="gpg-keys-github-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the GPG section, select &lt;em&gt;New GPG key&lt;/em&gt;. In the text field provided, paste the public key you exported previously.&lt;/p&gt;

&lt;p&gt;Once you push your commit, you will see it listed as "Verified" by Github.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v4-46p-2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://photos.davidboland.site/debpu06-blog-container/55519dbf-6959-421b-969b-77f32aa389f3-github-signed-commit-min.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v4-46p-2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://photos.davidboland.site/debpu06-blog-container/55519dbf-6959-421b-969b-77f32aa389f3-github-signed-commit-min.png" alt="github-signed-commit-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Signing Releases
&lt;/h2&gt;

&lt;p&gt;PGP also provides a method for signing files. This is useful for signing release packages and executables. This allows users to verify the author and integrity of the package. Users may want this level of verification for security reasons. Especially if the package handles sensitive information.&lt;/p&gt;

&lt;p&gt;There are three methods for signing with GPG. Signing, clear signing, and detached signing. &lt;/p&gt;

&lt;p&gt;Standard signing and clear signing both effect the file itself. Standard signing is used with encryption. Clear signing wraps the input with plaintext signature. Since we don't want this type of modification, we will work with detached signature.&lt;/p&gt;

&lt;p&gt;Detached signing creates a signature in a separate file. We can then provide the package, and provide the signature file from a trusted source. The user can then verify the package against it.&lt;/p&gt;

&lt;p&gt;To create a signed file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--detach-sign&lt;/span&gt; &lt;span class="nt"&gt;--sign-with&lt;/span&gt; DFD20A3D39A1913 &lt;span class="nt"&gt;-o&lt;/span&gt; package.sig package.exe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--detach-sign&lt;/code&gt; flag indicates that we want a detached signature. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--sign-with&lt;/code&gt; flag allows you to provide the id of the key you want to sign with. &lt;/p&gt;

&lt;p&gt;The final flag, &lt;code&gt;-o&lt;/code&gt; allows you to specify the output file. Traditionally you use either a &lt;em&gt;.sig&lt;/em&gt; or a &lt;em&gt;.gpg&lt;/em&gt; extension. &lt;/p&gt;

&lt;p&gt;And finally you specify the file you want to sign. In order to perform verification, you run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--verify&lt;/span&gt; package.sig package.exe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The think the idea of signing is pretty awesome. As developers, we sometimes forget how much reach our work can have. As code/programs are shared online, it can be beneficial to verify its source.&lt;/p&gt;

&lt;p&gt;This concept of signing isn't fool proof. Users can opt not to validate. Signers can loose their private keys. And the signature doesn't imply the code itself can be trusted. Signatures can only verify its source. But when done correctly, code signing can be useful.  &lt;/p&gt;

&lt;p&gt;As always, if you have any questions. Either about signing, or encryption in general, feel free to reach out.&lt;/p&gt;

</description>
      <category>encryption</category>
      <category>git</category>
    </item>
  </channel>
</rss>
