<?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>Forem: Mark Catalano</title>
    <description>The latest articles on Forem by Mark Catalano (@mcat).</description>
    <link>https://forem.com/mcat</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%2F72945%2Fc1d23359-e7d1-4b74-8397-bd771a1d5cf5.jpeg</url>
      <title>Forem: Mark Catalano</title>
      <link>https://forem.com/mcat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mcat"/>
    <language>en</language>
    <item>
      <title>Dev Tool Startup Founders, Share you Accelerator Story!</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Fri, 02 Aug 2019 12:49:03 +0000</pubDate>
      <link>https://forem.com/takeshape/dev-tool-founders-share-you-accelerator-story-49f8</link>
      <guid>https://forem.com/takeshape/dev-tool-founders-share-you-accelerator-story-49f8</guid>
      <description>&lt;p&gt;I'm currently going through Techstars with my startup &lt;a href="https://www.takeshape.io"&gt;TakeShape&lt;/a&gt;. Have you built a dev tool company? Gone through an accelerator? Done both at the same time!? I'd love to get your advice and hear your story! &lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Use The New Netlify Addon CLI Command To launch A Gatsby Site On Netlify In 2 Minutes</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Tue, 23 Apr 2019 13:01:43 +0000</pubDate>
      <link>https://forem.com/takeshape/how-to-use-netlify-addon-and-dev-with-gatsby-and-takeshape-1n4o</link>
      <guid>https://forem.com/takeshape/how-to-use-netlify-addon-and-dev-with-gatsby-and-takeshape-1n4o</guid>
      <description>&lt;p&gt;TLDR: Scroll down to the example to see how to use &lt;code&gt;netlify addons:create takeshape --template shape-portfolio&lt;/code&gt; and &lt;code&gt;netlify dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Launching a new Gatsby project with TakeShape and Netlify was already easy; but we don’t just want TakeShape to be easy to use, we want TakeShape to be super duper easy to use. That’s why we’re really excited about Netlify’s two latest additions to their CLI: &lt;code&gt;addons&lt;/code&gt; and &lt;code&gt;dev&lt;/code&gt;. Getting a live site running Gatsby, with content powered by TakeShape, takes less than two minutes. &lt;/p&gt;

&lt;p&gt;Here are a few ways to spend those three extra minutes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Listen to 3 episodes of &lt;a href="https://www.scientificamerican.com/podcast/60-second-science/" rel="noopener noreferrer"&gt;60-second science&lt;/a&gt; 🎧&lt;/li&gt;
&lt;li&gt;Donate to &lt;a href="https://www.classy.org/give/77372/#!/donation/checkout" rel="noopener noreferrer"&gt;a good cause&lt;/a&gt; 💰&lt;/li&gt;
&lt;li&gt;3-minute meditation on the benefits of the JAMstack 🧘(ommm-JAMstack-ommm)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll talk a bit about each of the new commands separately and then see them in action together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;netlify addon&lt;/code&gt; command&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add-ons are a &lt;a href="https://www.netlify.com/docs/partner-add-ons/" rel="noopener noreferrer"&gt;new feature&lt;/a&gt; from Netlify which allow you to quickly provision external services for your Netlify-hosted site. Besides creating the addon command, Netlify is also building an addon marketplace. We want developers who use TakeShape to be able to be early adopters of this awesome new feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;netlify dev&lt;/code&gt; command&lt;/strong&gt;&lt;br&gt;
Matt Biilman, co-founder of Netlify, announced the dev feature at the recent JAMstack_conf_nyc. His presentation was pretty rad and I recommend checking it out, especially the part where he live codes in vim: &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/RL_gtVZ_79Q"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Dev allows you to virtualize the Netlify stack on your local dev machine. This is crazy awesome! The power this gives to a developer really can’t be understated and I have to give it up to Netlify for continuously elevating the developer experience. To use the &lt;code&gt;netlify dev&lt;/code&gt; command, you’ll need to have the latest version of the Netlify CLI installed - run &lt;code&gt;npm install netlify-cli -g&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here’s what you can do with it at a high level:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;netlify dev&lt;/code&gt; starts a local dev server for the build tool you're using&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;netlify dev:exec &amp;lt;command&amp;gt;&lt;/code&gt; runs a shell command within the netlify dev environment&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;netlify functions:create&lt;/code&gt; bootstrap a new function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One more thing!&lt;br&gt;
&lt;code&gt;netlify dev --live&lt;/code&gt; lets you share your dev environment with anyone on a live url! What! Amazing!&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/netlify/netlify-dev-plugin" rel="noopener noreferrer"&gt;repo&lt;/a&gt; for complete documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EXAMPLE - Put’em both together! Using TakeShape’s Netlify addon with Gatsby&lt;/strong&gt;&lt;br&gt;
The TakeShape add-on really shines when used with an external SSG like Gatsby. The add-on makes your life easier by doing 3 things. &lt;/p&gt;

&lt;p&gt;Here we go!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Setup Netlify&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Fork the &lt;a href="https://github.com/takeshape/shape-portfolio-gatsbyjs" rel="noopener noreferrer"&gt;shape-portfolio-gatsbyjs&lt;/a&gt; repo 🍴&lt;/li&gt;
&lt;li&gt;Visit &lt;a href="https://app.netlify.com/start" rel="noopener noreferrer"&gt;https://app.netlify.com/start&lt;/a&gt; to create a new Netlify site from the forked repo 🆕&lt;/li&gt;
&lt;li&gt;Clone the forked &lt;code&gt;shape-portfolio-gatsbyjs&lt;/code&gt; repo 👯&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;netlify link&lt;/code&gt; to link the working directory to the netlify site 🔗&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TakeShape add-on&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;netlify addons:create takeshape --template shape-portfolio&lt;/code&gt; 🎶
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjj9eosa75f8p3rzl1i39.png" alt="TakeShape successful add-on provisioning"&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;netlify addons:auth takeshape&lt;/code&gt; 🔐&lt;/li&gt;
&lt;li&gt;Follow the instructions to create a TakeShape account and claim the TakeShape project ✅&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change content&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Change some content in the TakeShape project ✏️&lt;/li&gt;
&lt;li&gt;From Netlify, observe Gatsby build on Netlify, visit the deployed site, celebrate 🕺&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local Dev&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You’ll probably want to make some code changes and do a little local dev. This is where the new &lt;code&gt;dev&lt;/code&gt; command comes in. From your local working directory, run &lt;code&gt;netlify dev&lt;/code&gt;. This takes care of the hard work of getting your TakeShape API keys configured in your local environment. Make your code changes, commit to git, and then your site will redeploy with your changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And you’re done! This gets you up and running with TakeShape, Gatsby and Netlify in a few short minutes. You can stop right here and just start making copy changes. You now have a URL that you can share with the world! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s Next&lt;/strong&gt;&lt;br&gt;
We want devs to be able to do this even faster! We’re working on being able to launch a TakeShape powered site with a single click directly from any of the TakeShape sample project Github repos. &lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>tutorial</category>
      <category>gatsby</category>
      <category>webdev</category>
    </item>
    <item>
      <title>15 Powerful Tools To Add Advanced Functionality To Your JAMstack Project</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Mon, 07 Jan 2019 21:00:17 +0000</pubDate>
      <link>https://forem.com/takeshape/15-powerful-tools-to-add-advanced-functionality-to-your-jamstack-project-3ma5</link>
      <guid>https://forem.com/takeshape/15-powerful-tools-to-add-advanced-functionality-to-your-jamstack-project-3ma5</guid>
      <description>&lt;p&gt;The JAMstack makes it easier to create rich sites than ever before, which means your projects will be &lt;a href="https://www.takeshape.io/articles/why-the-best-websites-are-static/"&gt;more secure, more stable, and more affordable&lt;/a&gt; than ever before. &lt;/p&gt;

&lt;p&gt;Running a JAMstack site requires a slight change in the way you think about architecting your project. A successful JAMstack site is all about composing the best services for your specific project. When you want to deliver dynamic experiences like form submissions, search, and server-side data processing you’ve got lots of options to choose from. An entire crop of new services has grown to handle so many of use-cases that you’d once dedicate an entire server towards.&lt;/p&gt;

&lt;p&gt;Building with the JAMstack means you can avoid maintaining your own server, add powerful features to your project without nearly as much code, and focus your time on building a great user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Form Endpoints
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--weYP4hfB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jvgp0l1pg0vrxi6nrktj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--weYP4hfB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jvgp0l1pg0vrxi6nrktj.png" alt="Basic Froms as a Service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It used to be that one of the biggest downsides of running a static-site was that there was no good way of handling form submissions. Luckily, a bouquet of companies has arisen to handle this simple, common task for you. Simply provide their unique address as your form’s &lt;code&gt;action&lt;/code&gt;, and they’ll serialize, store, and even send along your data to webhooks. There are lots of options to choose from (see below), but so far &lt;a href="https://usebasin.com/"&gt;Basin&lt;/a&gt; seems to be the best value of the bunch with unlimited forms and unlimited submissions for $5/mo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other great solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://formkeep.com/"&gt;Formkeep&lt;/a&gt;, &lt;a href="https://formcarry.com/"&gt;Formcarry&lt;/a&gt;, &lt;a href="https://fieldgoal.io/"&gt;FieldGoal&lt;/a&gt;, &lt;a href="https://www.formbackend.com/"&gt;FormBackend&lt;/a&gt;, and &lt;a href="https://pageclip.co/"&gt;PageClip&lt;/a&gt; all offer similar functionality to Basin. There’s probably even more than we can list here. Take a look, compare them, and pick the one that’s right for you.&lt;/li&gt;
&lt;li&gt;If you’re already using Netlify, then &lt;a href="https://www.netlify.com/docs/form-handling/"&gt;their built-in form handling&lt;/a&gt; is probably your best bet. This way, you can avoid adding extra complexity by keeping all your site’s data together in one place.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://zapier.com/apps/webhook/integrations"&gt;Zapier Webhooks&lt;/a&gt; is a great DIY solution if you want to hack something together yourself. You can set your form’s action to your Zapier webhook, then pass the data along to any other service you can think of.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Search
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YNYSUp4d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3s92vz6e41gxazmdrk9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YNYSUp4d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3s92vz6e41gxazmdrk9q.png" alt="Algolia"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search could well be the heaviest burden of your project. It’s a tricky situation: search is incredibly difficult to do well, but it’s a UI feature that users expect to be done—and be done perfectly. Luckily, search services like &lt;a href="https://www.algolia.com/"&gt;Algolia&lt;/a&gt; make it easy to deliver a sophisticated search experience without building it from the ground up. They offer a Search API for indexing and ranking your project’s content, as well as pre-built interface elements in a variety of frameworks to let you drop in a search tool that works wonderfully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other great solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.searchiq.co/"&gt;SearchIQ&lt;/a&gt; offers a smaller set of features as Algolia, but at a lower price. One notable difference is they provide crawling of your project, which saves you from building the index yourself. They also provide drop-in JavaScript tools to provide autocomplete and search result pages.&lt;/li&gt;
&lt;li&gt;For a different take on this problem, &lt;a href="https://lunrjs.com/"&gt;Lunr&lt;/a&gt; provides a client-side search solution. If you’re rendering out a static site with a limited amount of content, say a blog or store, this could make for a great alternative. After rendering a static index file, Lunr will build a searchable index that you can cache in the browser's localStorage for future visits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9iHNdD39--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wuvxq0gxkhyyn2erfc08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9iHNdD39--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wuvxq0gxkhyyn2erfc08.png" alt="Auth0"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Authentication is tricky to get right and the consequences for making a mistake are huge. If you want to maintain user identities as part of your project, stick with an off-the-shelf solution like  &lt;a href="https://auth0.com/"&gt;Auth0&lt;/a&gt;. They provide a single-sign-on platform, an embeddable log-in widget, and advanced security features like multi-factor authentication and password-less login. Robust documentation and developer SDKs will make it easy to integrate Auth0 into your project. And, with 7k free active users and unlimited logins, they’re one of the most affordable services for getting your project up off the ground.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other great solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netlify is &lt;a href="https://www.takeshape.io/articles/how-to-publish-a-jamstack-site-to-netlify-in-less-than-2-minutes-with-takeshape/"&gt;a great service for hosting your JAMstack site&lt;/a&gt;, and one of the many reasons for that is the &lt;a href="https://www.netlify.com/docs/identity/"&gt;Netlify Identity&lt;/a&gt; add-on service they provide. You’ll get up to 1000 active users for free, easy connections to external identity providers like Google and GitHub, and authentication widgets to add to your site. If you’re already running your JAMstack project on Netlify (and you should consider it!), this is an easy choice.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/cognito/"&gt;AWS Cognito&lt;/a&gt; is the most affordable option, but it’s also harder to implement than the off-the-shelf solutions provided by Auth0. However, the aws-amplify library makes it much easier to integrate AWS into your JAMstack app. If you’re already using AWS to power the rest of your product’s services, then it may pay off to look into using Cognito first.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Functions as a Service (FaaS)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GdRAxIm5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8ja3x6dkaewju59j4i1j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GdRAxIm5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8ja3x6dkaewju59j4i1j.jpg" alt="Zeit Now"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Serverless functions are one of the most exciting parts of the JAMstack. Using a FaaS allows you to add just about any functionality you can imagine to your JAMstack site. For example, if none of the form providers we mentioned float your boat, spin up a serverless function and roll your own. Gives you tons of flexibility without having to worry about the underlying server or infrastructure. When you’re not using the function you’re not being billed for it. The grand-daddy of FaaS is &lt;a href="https://aws.amazon.com/lambda/"&gt;AWS lambda&lt;/a&gt;. AWS Lambda functions are our go-to at TakeShape, in-fact, TakeShape itself runs on AWS Lambda.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other great solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netlify Functions - basically a front for AWS lambda functions. If you’re using Netlify to host your JAMstack site and you like the convenience of centralized billing then Netlify functions are for you.&lt;/li&gt;
&lt;li&gt;Google Cloud Functions (&lt;a href="https://cloud.google.com/functions/"&gt;https://cloud.google.com/functions/&lt;/a&gt;) - Programmable cloud functions. Just like AWS lambda functions, but provided by Google. Good for being the recipient of a Webhook triggered by TakeShape.&lt;/li&gt;
&lt;li&gt;Zeit Now - &lt;a href="https://zeit.co/now"&gt;https://zeit.co/now&lt;/a&gt; - An up-and-comer with an incredibly easy to use CLI.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://zapier.com/apps/webhook/integrations"&gt;Zapier Webhooks&lt;/a&gt; is a great DIY solution if you just want to connect two services without doing any coding. It can save you a bunch of time, but the downside is that the functions can cost you much more to run if you use them frequently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Headless Content Management Systems (CMS)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hyfZHB4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/txboxrz9rbl26br29doe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hyfZHB4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/txboxrz9rbl26br29doe.png" alt="TakeShape"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, to manage the content of your JAMstack project you’ll want an easy-to-use CMS and static site generator. Leave folders of Markdown files behind and use &lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt;, a straightforward CMS and static site generator for organizing, developing, and deploying your JAMstack site. If you’re creating a web app, TakeShape’s GraphQL API provides a simple, easy-to-use endpoint to query for all your content at once. And best of all, TakeShape already provides sample projects that can get your site up and running within 5 minutes! You can try TakeShape for free and find that it’s the easiest way to manage content for your JAMstack site.&lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>10 Best Tools To Start Selling From A JAMstack Website</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Thu, 06 Dec 2018 19:04:15 +0000</pubDate>
      <link>https://forem.com/takeshape/10-simple-tools-to-start-selling-from-your-jamstack-website-40o5</link>
      <guid>https://forem.com/takeshape/10-simple-tools-to-start-selling-from-your-jamstack-website-40o5</guid>
      <description>&lt;p&gt;Why should you build your commerce experience on the JAMstack? 💰. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster performance - The faster a site is the more sales it generates.&lt;/li&gt;
&lt;li&gt;More security - Security breaches are costly and ruin reputations.&lt;/li&gt;
&lt;li&gt;More affordable to run - Process tons of transactions without scaling your own infrastructure.&lt;/li&gt;
&lt;li&gt;DX - Better Dev Experience = more time spent on customer UX.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Payments
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F00wylla1g1fgrp7my8ry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F00wylla1g1fgrp7my8ry.png" alt="Stripe Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you need to charge credit cards, you’ll want to use a payment gateway service like &lt;a href="https://stripe.com/" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt;. By sending payment information straight to them, you’ll avoid ever even seeing your customer’s payment information, leaving their all-important financial security to the highly-experienced team at Stripe. They provide an elegant dashboard, easy-to-use tools for refunding payments or handling disputed transactions, integration with hundreds of other services (including others in this list!), and a developer-friendly API for connecting their platform to your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other great solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.paypal.com/" rel="noopener noreferrer"&gt;PayPal&lt;/a&gt;, the online payments heavyweight, offers a similar API to Stripe and a plethora of integrations. One key difference is that unlike Stripe, you’ll need to collect payment details from customers during checkout—which could introduce security headaches for you down the road.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://braintreepayments.com" rel="noopener noreferrer"&gt;Braintree&lt;/a&gt;, is another worthwhile competitor to Stripe. It beats Stripe in the kinds of payments it accepts, including Venmo, but doesn’t integrate with as many other services. Unlike PayPal’s solution, you don’t need to touch customer’s payment information.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  E-commerce
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsb0wc2n5eqqc9uqknxzy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsb0wc2n5eqqc9uqknxzy.png" alt="Snipcart Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many giant e-commerce platforms that can provide you with a plain storefront, but if you want more control or need to layer e-commerce onto your existing site, then those platforms may not be the best choice. A service like &lt;a href="https://snipcart.com/" rel="noopener noreferrer"&gt;Snipcart&lt;/a&gt; can be a great choice for quickly adding e-commerce to your JAMstack site, since it provides just the right balance of simple set-up and deep customization. With Snipcart, you’ll get a basic shopping cart and checkout interface, but also the ability to deeply customize appearance and behavior. You’ll also get a dashboard for managing your orders and more advanced features like shopping cart recovery and inventory management. Plus, they integrate with all the Payment Gateways listed above, so you’ll be able to get paid quickly and securely. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other great solutions:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://gumroad.com/" rel="noopener noreferrer"&gt;Gumroad&lt;/a&gt; is a simple, hands-off solution designed for creators. Whether you’re an indie selling artwork, apps, or articles, you can quickly set up a store on Gumroad, add their buy button to your website, and get back to work. However, while Gumroad’s widgets are well-designed and attractive, if you want to customize the look-and-feel of your checkout, then you’ll want to go with a different service.&lt;/li&gt;
&lt;li&gt;On the other hand, &lt;a href="https://www.foxy.io/" rel="noopener noreferrer"&gt;Foxy&lt;/a&gt; tends more towards deep customization over quick set-up. It’s the most powerful and customizable of the solutions listed here, but much more geared towards developers than merchants. If you need more than just a shopping cart and a checkout, then you may want to look elsewhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Memberships
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7avkpv2tk4vgi5pzbj7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7avkpv2tk4vgi5pzbj7f.png" alt="Memberful Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While e-commerce sites provide the ability to sell goods, selling subscriptions to your site can be much more complex. If you want to provide subscribers with special newsletters, access to paywalled content, and more, you’ll want to go with a specialized subscription service like &lt;a href="https://memberful.com/" rel="noopener noreferrer"&gt;Memberful&lt;/a&gt;. At its core, Memberful combines simple subscription flows and management with integrations into the most common tools for content creation and management like Wordpress, Mailchimp, and Discourse. One TakeShape customer, &lt;a href="https://massivesci.com/" rel="noopener noreferrer"&gt;Massive Science&lt;/a&gt;, implemented Memberful for managing their community. Memberful gives them simple drop-in widgets for subscribing new members and for members to access their accounts, more advanced OAuth APIs for implementing authentication for paywalls and discussion forums, and newsletter integrations for maintaining special members-only mailing lists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other great solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you’re building a web app, then you may want to consider a more API-driven subscription manager like &lt;a href="https://www.chargebee.com/" rel="noopener noreferrer"&gt;Chargebee&lt;/a&gt; and &lt;a href="https://recurly.com/" rel="noopener noreferrer"&gt;Recurly&lt;/a&gt;. While they expect you to provide your own front-end subscription interfaces, they’ll handle all the complex back-end logic for charging your subscribers and provide analytics to help you reduce churn.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Headless CMS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F38aznjtghrvzkrtoa4vr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F38aznjtghrvzkrtoa4vr.png" alt="Takeshape Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, you’ll want a website with an easy-to-use CMS in order to manage your products and categories, generate a secure and stable static site, and create a truly unique experience for your fans, members, or customers. &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;TakeShape&lt;/a&gt; is a straightforward CMS and static site generator for organizing, developing, and deploying your JAMstack site. If you’re creating a webapp, TakeShape’s GraphQL API provides a simple, easy-to-use endpoint to query for all your content at once. And best of all, TakeShape already provides a sample “Shape Store” project that can get your site up and running within 5 minutes! You can try TakeShape for free and find that it’s the easiest way to get started selling from your JAMstack site.&lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>All You Ever Wanted To Know About GraphQL</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Tue, 27 Nov 2018 20:54:57 +0000</pubDate>
      <link>https://forem.com/takeshape/all-you-ever-wanted-to-know-about-graphql-323h</link>
      <guid>https://forem.com/takeshape/all-you-ever-wanted-to-know-about-graphql-323h</guid>
      <description>&lt;p&gt;Co-founder of &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;TakeShape&lt;/a&gt;, Andrew Sprouse, presents GraphQL to a JAMstack meetup in New York.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/FgjHCt_9do4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accompanying Github repo: &lt;a href="https://github.com/takeshape/jamstack-meetup-graphql-demo" rel="noopener noreferrer"&gt;https://github.com/takeshape/jamstack-meetup-graphql-demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is GraphQL?
&lt;/h3&gt;

&lt;p&gt;Schema Definition + Query language + Resolution framework&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Provides a strongly typed description of your data&lt;/li&gt;
&lt;li&gt;Schema Description Language (SDL) is the recommended cross-platform way to specify schema.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;ACTOR&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;DIRECTOR&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Role&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;characterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Movie&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;filmography&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Movie&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;watched&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;poster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;actors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;]!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;director&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GraphQL Schema also specifies how you interact with your data with queries and mutations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;listMovies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Movie&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;addMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Movie&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;removeMovie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Movie&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query Langauge
&lt;/h3&gt;

&lt;p&gt;Query your data and fetch exactly what you need&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;getToWatchList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;watched&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;director&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"getToWatchList"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"watched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"movie"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Top Gun"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1985"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"director"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tony Scott"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"watched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"movie"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Big Trouble in Little China"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1986"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"director"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Carpenter"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"watched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"movie"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The Princess Bride"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1987"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"director"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rob Reiner"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"watched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"movie"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Taxi Driver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1976"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"director"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Martin Scorsese"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mutations
&lt;/h3&gt;

&lt;p&gt;Modify your data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;addMovieToWatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Die Hard"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;watched&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;movieTitle&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;director&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"addMovieToWatch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"watched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"movie"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Taxi Driver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1976"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"director"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Martin Scorsese"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"watched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"movie"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Die Hard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1988"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"director"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John McTiernan"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Resolution Framework
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Each GraphQL implementation provides it own query resolution framework&lt;/li&gt;
&lt;li&gt;GraphQL.js is the reference implementation&lt;/li&gt;
&lt;li&gt;Perform query and mutation resolution&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Schema (SDL)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;getToWatchList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ToWatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;addMovieToWatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ToWatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;removeMovieToWatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ToWatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;markMovieWatched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;watched&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ToWatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Resolvers
&lt;/h4&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;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;getToWatchList&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;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;WatchList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&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="na"&gt;Mutation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;addMovieToWatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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="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;WatchList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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="nf"&gt;removeMovieToWatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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="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;WatchList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&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="nf"&gt;markMovieWatched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watched&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;WatchList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markWatched&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="nx"&gt;watched&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;Resolvers are also able to resolve dynamically computed fields&lt;/p&gt;

&lt;h4&gt;
  
  
  Schema (SDL)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Move&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;poster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;actors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;director&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ToWatch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;movieTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Movie&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;watched&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Resolvers
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const resolvers = {
    ToWatch: {
        async movie(toWatch) {
            const info = await fetchMovieInfo(toWatch.movieTitle);
            return info ? {
                title: info.Title,
                rating: info.imdbRating,
                poster: info.Poster,
                year: info.Year,
                actors: info.Actors,
                director: info.Director
            } : null
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>graphql</category>
      <category>apollo</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>GraphQL + CMS = Peanut Butter + Jelly</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Wed, 21 Nov 2018 15:46:58 +0000</pubDate>
      <link>https://forem.com/takeshape/graphql--cms--peanut-butter--jelly-25b</link>
      <guid>https://forem.com/takeshape/graphql--cms--peanut-butter--jelly-25b</guid>
      <description>&lt;p&gt;I recently got the chance to present on the benefits of using GraphQL and Headless CMS to a JAMstack meetup in New York. The event was hosted by &lt;a href="https://www.thenewdynamic.org/" rel="noopener noreferrer"&gt;The New Dynamic&lt;/a&gt; at &lt;a href="https://postlight.com/" rel="noopener noreferrer"&gt;Postlight Studio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PDnrde2TyOY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Headless GraphQL CMS + SSG
&lt;/h2&gt;

&lt;p&gt;TakeShape's combo of Headless + GraphQL + Static Site Generator makes for a pretty sweet CMS for the JAMstack. That's a lot of jargon so I’ll break it down:&lt;/p&gt;

&lt;h3&gt;
  
  
  Headless
&lt;/h3&gt;

&lt;p&gt;Content is decoupled from presentation. The authoring environment is totally separate and disconnected from the website that your users interact with. &lt;br&gt;
Because your artifact is pre-rendered html, css and JavaScript your experience is more performant, more secure and more scalable.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL
&lt;/h3&gt;

&lt;p&gt;GraphQL is core to TakeShape. Every time you interact with content on TakeShape you’re interacting with GraphQL &lt;/p&gt;

&lt;h3&gt;
  
  
  CMS
&lt;/h3&gt;

&lt;p&gt;Some users may feel more comfortable interacting with something visual so we provide an interface for non-technical users to manage content.&lt;/p&gt;

&lt;h3&gt;
  
  
  Static Content Generator (Static Site Generator)
&lt;/h3&gt;

&lt;p&gt;We built a static site generator that we think of more as a Static content generator. It’s a step lower of an abstraction. You can use TakeShape's static content generator as a way to generate a static website. But we wanted to keep it simple. GraphQL query + Template = html. We let you to bring your own build system to handle JavaScript and CSS however you like.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model, Create, Develop, Use
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxm4jo6iedumbx7960q9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxm4jo6iedumbx7960q9.png" alt="Four Steps to using TakeShape - Model, Create, Develop, and Use" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deciding to use GraphQL
&lt;/h2&gt;

&lt;p&gt;There were some pros and cons that we thought about when we were making the decision to build TakeShape around a GraphQL API&lt;/p&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GraphQL was relatively new and not yet widely adopted. It’s first stable release was October 2016 and we started specing out TakeShape in August 2016&lt;/li&gt;
&lt;li&gt;Facebook's patent licensing terms that were restrictive. Thankfully that's been resolved. &lt;/li&gt;
&lt;li&gt;Rest was so familiar. Could we really convince people to use GraphQL?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Flashbacks to wrestling REST endpoints to mash up custom data. Trying to tie together multiple APIs or retrieve content from multiple entities at once is tricky. This is exactly why Facebook created GraphQL. &lt;/li&gt;
&lt;li&gt;Messing around with curl trying to figure out how an API worked. If you've ever used an API based CMS and you weren’t sure what fields you were going to get back to use in your templates you know this pain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  In the end, it came down to a few things
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Like most developers working with new technologies much more than we like working with something old and crufty.&lt;/li&gt;
&lt;li&gt;GraphQL drastically reduced the amount of code that we needed to write to actually get the our API working, which meant we could build TakeShape faster.&lt;/li&gt;
&lt;li&gt;The self-documenting features of GraphQL drastically simplify the experience of learning how to use TakeShape's API for new developers. And since we were building a tool where everyone’s API would essentially be up to their circumstance and their creativity it was important that learning how to interact with our TakeShape be easier.&lt;/li&gt;
&lt;li&gt;Most importantly we were our own guinea pigs. We find GraphQl queries to be easier for people to understand and work with. We knew we wanted to build a CMS that helped people who had similar problems to ourselves and saw the world like we did. 
It’s nice to look at and easy to understand what’s going on when you’re working with GraphQL.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;homepage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ homepage.title }}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ homepage.title }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"{{ homepage.image.path | image }}"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How we use GraphQL to build TakeShape
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;TakeShape is built around a GraphQL API. It’s not just our interface to other Developers. We use it to actually build the application. It’s not a bolt on &lt;/li&gt;
&lt;li&gt;TakeShape uses the same GraphQL API that we make available to users to build sites, to power the single page react web client for modeling and content creation, the CLI tool and the Static Content Generator.&lt;/li&gt;
&lt;li&gt;It’s how the entire app runs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwf60wgsael7xyickasq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwf60wgsael7xyickasq.png" alt="TakeShape's Collaborative Web UI, Static Site Generator, GraphQL QPI, Dev Tools, Hosting Via Third-parties" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using a GraphQL API to build a GraphQL CMS that provides a GraphQL API. It’s Meta!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyusu9dcgi787eho297rk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyusu9dcgi787eho297rk.gif" alt="TakeShape is Meta GraphQL" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Developers use TakeShape’s GraphQL API
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Making requests directly through the GraphQL endpoint&lt;/li&gt;
&lt;li&gt;Using the TakeShape Static Content Generator and writing GraphQL query files that retrieve content stored in TakeShape and is used to generate static sites&lt;/li&gt;
&lt;li&gt;Or by using Static Site Generators like Gatsby that play well with GraphQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffexk2lb29apb1cjqw7xj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffexk2lb29apb1cjqw7xj.png" alt="Directly with the GraphQL API, Using the SSG, Third parties like Gatsby" width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interested In Headless GraphQL CMS?&lt;br&gt;
TakeShape is a headless GraphQL CMS that makes building JAMstack sites easier. At TakeShape we're building the best tools for managing content possible for the most creative designers and developers. Our project templates, make it easy to get started. Plus, pricing is downright affordable. &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;Sign up for a free account&lt;/a&gt; and spend more time being creative!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>graphql</category>
      <category>jamstack</category>
      <category>cms</category>
    </item>
    <item>
      <title>Use Gatsby.js And TakeShape To Make Your JAMstack Site Sweeter</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Fri, 16 Nov 2018 20:42:41 +0000</pubDate>
      <link>https://forem.com/takeshape/use-gatsbyjs-and-takeshape-to-make-your-jamstack-site-sweeter-51og</link>
      <guid>https://forem.com/takeshape/use-gatsbyjs-and-takeshape-to-make-your-jamstack-site-sweeter-51og</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxaqq1rftv1qlk9jjwnf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxaqq1rftv1qlk9jjwnf.gif" alt="TakeShape and Gatsby" width="720" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is part 4 of our 4 part series. Check out &lt;a href="https://www.takeshape.io/articles/how-to-build-a-design-portfolio-with-takeshape/" rel="noopener noreferrer"&gt;part 1&lt;/a&gt; to get an introduction to TakeShape and learn content modeling and content creation. In &lt;a href="https://www.takeshape.io/articles/how-to-build-a-jamstack-website-with-takeshape/" rel="noopener noreferrer"&gt;part 2&lt;/a&gt;,  you’ll learn how to create a static site that loads data from &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;TakeShape&lt;/a&gt;. In &lt;a href="https://www.takeshape.io/articles/how-to-publish-a-jamstack-site-to-netlify-in-less-than-2-minutes-with-takeshape/" rel="noopener noreferrer"&gt;part 3&lt;/a&gt;, you’ll learn how to quickly deploy your new static site onto Netlify for a straightforward, secure, and speedy hosting solution.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; Short-circuit this tutorial and start playing around with the completed site. We won’t be offended! &lt;a href="https://app.takeshape.io/login" rel="noopener noreferrer"&gt;Login&lt;/a&gt; and create a new project with “Shape Portfolio” template. Then clone the completed project repo, check out the &lt;code&gt;README.md&lt;/code&gt; and start jamming.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git clone https://github.com/takeshape/takeshape-samples
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;takeshape-samples/shape-portfolio-gatsbyjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Bold And Adventurous Should Continue
&lt;/h2&gt;

&lt;p&gt;You’ve reached the final part of this series, which showed you how to create a static-site portfolio with &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;TakeShape&lt;/a&gt;. If you’ve been following along from the start you’re achieved quite a lot! You’ve created a content model and GraphQL API using TakeShape, used TakeShape’s static site generator to load your content into a fully customizable static site, and deployed your static site with Netlify.&lt;/p&gt;

&lt;p&gt;In this conclusion, you’re going to take your portfolio site to the next level by learning how to build it with &lt;a href="https://www.gatsbyjs.org/" rel="noopener noreferrer"&gt;Gatsby.js&lt;/a&gt;, a static site generator that layers modern web tools like React.js and Webpack on top of the speedy and secure foundation of a JAMstack website. Gatsby is another great JAMstack tool for generating a JAMstack site with data from GraphQL APIs, especially when it comes to highly-interactive web applications. And TakeShape makes for a wonderful CMS backend for all of your Gatsby sites since every TakeShape project has a GraphQL API that easily integrates with Gatsby.&lt;/p&gt;

&lt;p&gt;In this walkthrough, you’ll get started with Gatsby and translate your existing portfolio website into a React-based website. This is the most advanced walkthrough in this series, so if you haven’t already read through the previous articles, we recommended that you at least skim them first. &lt;/p&gt;

&lt;h2&gt;
  
  
  Hello Gatsby!
&lt;/h2&gt;

&lt;p&gt;Get started by cloning the Gatsby starter project “hello world” and making sure everything works. Install the required libraries and then run the developer site with &lt;code&gt;npm start&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git clone https://github.com/gatsbyjs/gatsby-starter-hello-world shape-portfolio-gatsbyjs
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;shape-portfolio-gatsbyjs
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit &lt;code&gt;localhost:8000&lt;/code&gt; in your browser to see the starter site running!&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect Gatsby to TakeShape
&lt;/h2&gt;

&lt;p&gt;Since they’re both built around GraphQL data, Gatsby and TakeShape fit together like Lego bricks. After you provide TakeShape as a datasource to Gatsby, you’ll be able to query your data right from your pages and components.&lt;/p&gt;

&lt;p&gt;To start, install the &lt;code&gt;gatsby-source-graphql&lt;/code&gt; and &lt;code&gt;dotenv&lt;/code&gt; plugins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npm &lt;span class="nb"&gt;install &lt;/span&gt;gatsby-source-graphql dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a &lt;code&gt;gatsby-config.js&lt;/code&gt; file in the project’s root to configure the plugin:&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="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;plugins&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="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby-source-graphql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;typeName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;takeshape&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Url to query from&lt;/span&gt;
                &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://api.takeshape.io/project/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TAKESHAPE_PROJECT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/graphql`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// HTTP headers&lt;/span&gt;
                &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&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;Content-Type&lt;/span&gt;&lt;span class="dl"&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;application/json&lt;/span&gt;&lt;span class="dl"&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;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TAKESHAPE_TOKEN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="c1"&gt;// Additional options to pass to node-fetch&lt;/span&gt;
                &lt;span class="na"&gt;fetchOptions&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;You’ll notice that this configuration uses &lt;code&gt;TAKESHAPE_PROJECT&lt;/code&gt; and &lt;code&gt;TAKESHAPE_TOKEN&lt;/code&gt; values from our local environment. We’ll keep these values in our environment so that we don’t inadvertently commit these secrets to version control.&lt;/p&gt;

&lt;p&gt;The Gatsby starter project should already contain a &lt;code&gt;.gitignore&lt;/code&gt; file that includes &lt;code&gt;.env&lt;/code&gt;, but you might want to double check, just in case.&lt;/p&gt;

&lt;p&gt;Then, &lt;a href="https://www.takeshape.io/docs/creating-an-api-key/" rel="noopener noreferrer"&gt;create a read-only TakeShape API token&lt;/a&gt; and copy your project’s ID from its URL in the TakeShape web client. Finally, create a file named &lt;code&gt;.env&lt;/code&gt; in the root of your project that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;TAKESHAPE_PROJECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;YOUR-PROJECTS-ID&amp;gt;
&lt;span class="nv"&gt;TAKESHAPE_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;YOUR-API-TOKEN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test your connection
&lt;/h3&gt;

&lt;p&gt;Start your Gatsby development server with &lt;code&gt;gatsby develop&lt;/code&gt;. As long as the configuration is correct, you’ll see the server start successfully and be able to test your connection to TakeShape with the built-in GraphiQL IDE.&lt;/p&gt;

&lt;p&gt;Once the server has started, navigate to &lt;code&gt;http://localhost:8000/___graphql&lt;/code&gt; in your browser. You’ll see a page that looks like the API Explorer in TakeShape—because it’s the same software!&lt;/p&gt;

&lt;p&gt;Test that you can access your portfolio projects through Gatsby with this GraphQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;takeshape&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;getProjectList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you type this in, you should see the different fields autocomplete. Then, when you run the query you should see the total number of portfolio projects you’ve created in TakeShape so far. As you can see, Gatsby can easily talk to TakeShape, figure out the schema for your entire project, and let you pull that data right into your Gatsby project.&lt;/p&gt;

&lt;p&gt;Now, we can start recreating our portfolio in React!&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating from Nunjucks to React
&lt;/h2&gt;

&lt;p&gt;We’ll start by creating pages for each project in your portfolio, then move onto the simpler task of recreating the home and about pages.&lt;/p&gt;

&lt;p&gt;But before we do any of that, we need to migrate the base layout and structure over to React!&lt;/p&gt;

&lt;h3&gt;
  
  
  Layout
&lt;/h3&gt;

&lt;p&gt;First we’ll create a folder named &lt;code&gt;layouts&lt;/code&gt; within the &lt;code&gt;src&lt;/code&gt; directory of our project. Then we’ll create a file named &lt;code&gt;default.js&lt;/code&gt;. You can do this in two commands, from the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir &lt;/span&gt;src/layouts &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;touch &lt;/span&gt;src/layouts/default.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;default.js&lt;/code&gt; layout will be very similar in purpose to the &lt;code&gt;default.html&lt;/code&gt; layout in the Nunjucks template you created for your &lt;code&gt;shape-portfolio&lt;/code&gt; in part 2, though since it’s built with React, it’ll look slightly different:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prop-types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/footer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Menu&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/menu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./default.css&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;Layout&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="nx"&gt;siteTitle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shape Portfolio&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;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;container&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;Menu&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;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;main&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;/div&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="nx"&gt;Footer&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="sr"&gt;/div&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;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&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;isRequired&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;Layout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The purpose of this component is to provide a basic layout from which all your pages can inherit. By wrapping your other components with this layout, you can ensure that all the pages in your project maintain a consistent appearance and don’t duplicate any functionality. You’ll make &lt;code&gt;children&lt;/code&gt; a required property of the Layout component, since it should always be acting as a wrapper for something else, whether that’s a list of projects, a project itself, or something else entirely.&lt;/p&gt;

&lt;p&gt;Next create a &lt;code&gt;default.css&lt;/code&gt; file in the same &lt;code&gt;src/layouts&lt;/code&gt; directory. You’ll notice that it gets imported right into this &lt;code&gt;default.js&lt;/code&gt; file as well. Now you might be saying, “Importing CSS into JS? That’ll never work!” Well since Gatsby comes with Webpack built in, it’ll extract and bundle all your CSS when it’s time to build your site. This has the benefit of letting you keep your styles right alongside your components.&lt;/p&gt;

&lt;p&gt;For now, go ahead and copy the &lt;code&gt;main.css&lt;/code&gt; styles from the &lt;code&gt;shape-portfolio&lt;/code&gt; project into &lt;code&gt;default.css&lt;/code&gt;. You won’t be diving into advanced styling in this walkthrough, although the &lt;a href="https://www.gatsbyjs.org/docs/styling/" rel="noopener noreferrer"&gt;fancier CSS-in-JS techniques that Gatsby supports with additional plugins&lt;/a&gt; are worth exploring in more depth.&lt;/p&gt;

&lt;h4&gt;
  
  
  Header &amp;amp; Footer
&lt;/h4&gt;

&lt;p&gt;In your &lt;code&gt;default.js&lt;/code&gt; layout, the Header, Footer, and Menu are all abstracted into standalone components. You’ll start by creating the Header file, which will provide all the the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tags for your project.&lt;/p&gt;

&lt;p&gt;Start by adding the &lt;code&gt;react-helmet&lt;/code&gt; and &lt;code&gt;gatsby-plugin-react-helmet&lt;/code&gt; packages to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npm &lt;span class="nb"&gt;install &lt;/span&gt;react-helmet gatsby-plugin-react-helmet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add &lt;code&gt;gatsby-plugin-react-helmet&lt;/code&gt; to your list of plugins in your &lt;code&gt;gatsby-config.js&lt;/code&gt; file:&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&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;gatsby-plugin-react-helmet&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="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby-source-graphql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/nfl/react-helmet" rel="noopener noreferrer"&gt;React Helmet&lt;/a&gt; is an easy-to-use component for managing the document head of all of your pages. It will append the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tags you provide to the beginning of every page you include it on—and since you’re including it in your default layout, it’ll be included in every page.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;src&lt;/code&gt; directory, create a new &lt;code&gt;components&lt;/code&gt; directory and inside it create a new file named &lt;code&gt;header.js&lt;/code&gt; that looks like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Helmet&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-helmet&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;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;siteTitle&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Helmet&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;html&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&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;title&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;siteTitle&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;/title&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="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;charSet&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&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;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viewport&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;width=device-width, initial-scale=1&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;link&lt;/span&gt;
            &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://fonts.googleapis.com/css?family=Work+Sans:400,500,600,700&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stylesheet&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="sr"&gt;/Helmet&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all it takes to create a Header component, to be imported and used by your default layout.&lt;/p&gt;

&lt;p&gt;Next create your site’s footer in &lt;code&gt;src/components/footer.js&lt;/code&gt;. This component is simpler:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&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;Footer&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;footer&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;footer&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;p&lt;/span&gt;&lt;span class="o"&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;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()}{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&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="nx"&gt;a&lt;/span&gt;
                &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://takeshape.io&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer nofollow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;TakeShape&lt;/span&gt; &lt;span class="nx"&gt;Inc&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;/a&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;/p&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;/footer&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Footer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll notice that this footer contains our first piece of dynamic content: the copyright date will automatically reflect the current year by using the &lt;code&gt;new Date().getFullYear()&lt;/code&gt; function. The ability to use JavaScript inside of components is one of the most powerful aspects of React!&lt;/p&gt;

&lt;h4&gt;
  
  
  Menu
&lt;/h4&gt;

&lt;p&gt;The final layout component that you’ll create will also be the first one to query data from your TakeShape project. To enable this functionality, you’ll use the &lt;a href="https://www.gatsbyjs.org/docs/static-query/#static-query" rel="noopener noreferrer"&gt;&lt;code&gt;StaticQuery&lt;/code&gt; API&lt;/a&gt; provided by Gatsby. With &lt;code&gt;StaticQuery&lt;/code&gt;, a component can individually request the data that it needs to render. This is a great fit for your Menu component, since it’ll render the same on every page regardless of what other content the page contains.&lt;/p&gt;

&lt;p&gt;In order to render images from TakeShape, you’ll also use the &lt;code&gt;getImageUrl&lt;/code&gt; API provided by TakeShape’s &lt;code&gt;takeshape-routing&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;First, install the &lt;code&gt;takeshape-routing&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npm &lt;span class="nb"&gt;install &lt;/span&gt;takeshape-routing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create a &lt;code&gt;src/components/menu.js&lt;/code&gt; component that looks like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StaticQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getImageUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;takeshape-routing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../routes&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;menuQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    takeshape {
      projects: getProjectList {
        items {
          name
        }
      }
      about: getAbout {
        socialProfiles {
          profileUrl
          socialNetwork
          socialNetworkIcon {
            path
          }
        }
      }
    }
  }
`&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;Menu&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;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="nx"&gt;nav&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;menu&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;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;menu__container&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;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;site-name&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;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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;strong&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Shape&lt;/span&gt; &lt;span class="nx"&gt;Portfolio&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/strong&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;/Link&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;/p&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="nx"&gt;ul&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;nostyle&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takeshape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&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;i&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;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;/Link&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;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/ul&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="nx"&gt;hr&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;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;About&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&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="nx"&gt;ul&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;nostyle inline&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takeshape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;about&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socialProfiles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&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;social-profile&lt;/span&gt;&lt;span class="dl"&gt;"&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;i&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;a&lt;/span&gt;
              &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profileUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
              &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&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;img&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;social-network-icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;getImageUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socialNetworkIcon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Social network icon&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;span&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;social-network-name&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;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socialNetwork&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;/span&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;/a&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;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/ul&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/nav&lt;/span&gt;&lt;span class="err"&gt;&amp;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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StaticQuery&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;menuQuery&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&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;Menu&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&amp;gt;} /&lt;/span&gt;&lt;span class="o"&gt;&amp;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 menu consists of two objects: a query for the data we want to include and a component to render it. At the bottom of the file, the two objects get passed to Gatsby’s &lt;code&gt;StaticQuery&lt;/code&gt; API, which takes on the work of fetching the data and rendering the component.&lt;/p&gt;

&lt;p&gt;The menu also makes use of Gatsby’s &lt;code&gt;Link&lt;/code&gt; component. Notice how you use &lt;code&gt;Link&lt;/code&gt; to link within your site, as you would link to a project page, while you use a standard anchor to link outside your site, as you would link to a social network. When you use &lt;code&gt;Link&lt;/code&gt;, Gatsby can load these new pages dynamically with Javascript, preventing additional page loads. It’s a slick out-of-the-box feature.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;Link&lt;/code&gt; uses the function &lt;code&gt;routes.project&lt;/code&gt; to set its destination. You’ll need to create that function yourself. Luckily, that’s the next step!&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Pages
&lt;/h3&gt;

&lt;p&gt;You’ll want to create a standalone page for every project, so that you can link directly to different projects in your portfolio. But, each page should also be created dynamically, based on data from TakeShape. So how can you go about creating pages dynamically?&lt;/p&gt;

&lt;p&gt;First, create a new file named &lt;code&gt;gatsby-node.js&lt;/code&gt; in your site’s root directory. This will contain code that’s executed by Gatsby’s build process. You’ll plug-in to Gatsby’s &lt;code&gt;createPages&lt;/code&gt; API to create a standalone page for each of your portfolio’s projects.&lt;/p&gt;

&lt;p&gt;First create the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;touch &lt;/span&gt;gatsby-node.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add your function:&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;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&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;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/routes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createPages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;graphql&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="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="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    query {
      takeshape {
        projects: getProjectList {
          items {
            _id
            name
          }
        }
      }
    }
  `&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;takeshape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&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="nx"&gt;name&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;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/components/Project.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;projectId&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="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 function will first query TakeShape for a list of all the project names and IDs. Then, for each project, you’ll use the &lt;code&gt;actions.createPage&lt;/code&gt; API to create its standalone page. Each page will need three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A path, which you’ll generate using a routing function using the project’s name.&lt;/li&gt;
&lt;li&gt;A component, which you’ll create to render the project’s page.&lt;/li&gt;
&lt;li&gt;A context, which you’ll provide to each project page’s individual GraphQL query,&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Creating your Project path
&lt;/h4&gt;

&lt;p&gt;You’ll create the function to generate a route for the project. First create a file named &lt;code&gt;routes.js&lt;/code&gt; in the &lt;code&gt;src&lt;/code&gt; directory and add the &lt;code&gt;slugify&lt;/code&gt; package to your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;touch &lt;/span&gt;src/routes.js  
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npm &lt;span class="nb"&gt;install &lt;/span&gt;slugify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, in &lt;code&gt;src/routes.js&lt;/code&gt;, add a function for creating routes for your projects based on their names:&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;slugify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slugify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&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;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;slugify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`/projects/&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="s2"&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;As you add other dynamically-generated pages to your portfolio, you can add their routing rules to this same file.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating your Project component and query
&lt;/h4&gt;

&lt;p&gt;Your component will render the entire project, which you’ll wrap in the &lt;code&gt;Layout&lt;/code&gt; component you already created. This will render a complete page for each project!&lt;/p&gt;

&lt;p&gt;Start by creating a file named &lt;code&gt;Project.js&lt;/code&gt; in your &lt;code&gt;src/components&lt;/code&gt; directory that looks like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getImageUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;takeshape-routing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../layouts/default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProjectMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;client&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;startYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&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;endYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;endDate&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;includeEndYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;endYear&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;startYear&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;endYear&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="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;project__metadata&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;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;project__metadata&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;startYear&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;includeEndYear&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`&amp;amp;endash; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;endYear&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&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;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;client&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="nx"&gt;p&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;a&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;/a&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;/p&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="dl"&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;project&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&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;project&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;header&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;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverImage&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="nx"&gt;img&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;project__cover-image&lt;/span&gt;&lt;span class="dl"&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;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;getImageUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crop&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&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="nx"&gt;h1&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;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;/h1&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="nx"&gt;ProjectMetadata&lt;/span&gt;
        &lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&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;/header&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="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;project__description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&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;/article&lt;/span&gt;&lt;span class="err"&gt;&amp;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="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="o"&gt;=&amp;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="nx"&gt;Layout&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;Project&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="o"&gt;=&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;takeshape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project&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;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query($projectId: ID!) {
    takeshape {
      project: getProject(_id: $projectId) {
        name
        startDate
        endDate
        coverImage {
          description
          path
        }
        client {
          name
          url
        }
        description: descriptionHtml
      }
    }
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Starting from the bottom, this file exports a query for an individual project and component that renders the complete project page, both of which are used by the &lt;code&gt;createPage&lt;/code&gt; API.  The query accepts the &lt;code&gt;context&lt;/code&gt; you provided to the &lt;code&gt;createPage&lt;/code&gt; API and fetches data for each Project page. It then provides it to the page with the &lt;code&gt;data&lt;/code&gt; parameter. The page wraps the Project component in the Layout component in order to render the complete page.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Project&lt;/code&gt; component in this file provides the logic for actually rendering each project. It also uses a &lt;code&gt;ProjectMetadata&lt;/code&gt; subcomponent to handle the logic for formatting the project’s metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  Homepage
&lt;/h3&gt;

&lt;p&gt;Your homepage will provide a list of your projects, which we’ll create in a separate reusable component. The homepage will provide its own query for a list of projects, then pass it on to the &lt;code&gt;ProjectList&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The Gatsby starter project you used will already contain a file named &lt;code&gt;index.html&lt;/code&gt; in the &lt;code&gt;src/pages&lt;/code&gt; directory. &lt;code&gt;src/pages&lt;/code&gt; is a special directory in Gatsby: each file in this directory will automatically create its own standalone page, as long as the file exports at least a component.&lt;/p&gt;

&lt;p&gt;Update your &lt;code&gt;src/pages/index.html&lt;/code&gt; to be like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../layouts/default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ProjectList&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/ProjectList&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;IndexPage&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;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="nx"&gt;Layout&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;ProjectList&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="o"&gt;=&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;takeshape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;}&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;main&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="sr"&gt;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;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;IndexPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    takeshape {
      projects: getProjectList {
        items {
          name
          startDate
          coverImage {
            description
            path
          }
        }
      }
    }
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create a file named &lt;code&gt;ProjectList.js&lt;/code&gt; in your &lt;code&gt;src/components&lt;/code&gt; directory and make it look like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getImageUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;takeshape-routing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../routes&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;ProjectListItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;project&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;startYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&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;endYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endDate&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;includeEndYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;endYear&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;startYear&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;endYear&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;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&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;project&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;img&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;project__thumbnail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;getImageUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crop&lt;/span&gt;&lt;span class="dl"&gt;"&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;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&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="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;project__name&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;strong&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;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;/strong&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;/p&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="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;project__metadata&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;startYear&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;includeEndYear&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`&amp;amp;endash; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;endYear&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&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;/p&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;/Link&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProjectList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;projects&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;nostyle project-list&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;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&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;project-list--entry&lt;/span&gt;&lt;span class="dl"&gt;"&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;i&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;ProjectListItem&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&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;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;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;ProjectList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this file, the &lt;code&gt;ProjectList&lt;/code&gt; component renders a set of &lt;code&gt;ProjectListItem&lt;/code&gt; components. Each &lt;code&gt;ProjectListItem&lt;/code&gt; displays some limited information about the project and links to the Project page you’ve already made. This component doesn’t require a query to be included with it, since it’s not a standalone page and the data is provided by the &lt;code&gt;index.js&lt;/code&gt; file that includes it.&lt;/p&gt;

&lt;p&gt;At this point, you should be able to run &lt;code&gt;gatsby develop&lt;/code&gt;, navigate to &lt;code&gt;http://localhost:8000/&lt;/code&gt;, and see a list of projects. Clicking on any one of them should take you to that project’s page. It’s alive!&lt;/p&gt;

&lt;h3&gt;
  
  
  About and 404 Pages
&lt;/h3&gt;

&lt;p&gt;Finally, you’ll finish off by creating a standalone About page and a standalone 404 page. For the about page, you can create a file &lt;code&gt;about.js&lt;/code&gt; in &lt;code&gt;src/pages&lt;/code&gt; that looks like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getImageUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;takeshape-routing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../layouts/default&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;AboutPage&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;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="nx"&gt;Layout&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;article&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;about&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;img&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;about__portrait&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;getImageUrl&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;takeshape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;about&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;portrait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crop&lt;/span&gt;&lt;span class="dl"&gt;"&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="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;about__biography&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&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;takeshape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;about&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;biography&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;/article&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;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;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;AboutPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    takeshape {
      about: getAbout {
        biography: biographyHtml
        portrait {
          title
          description
          path
        }
      }
    }
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file should export your &lt;code&gt;AboutPage&lt;/code&gt; component and a query so that the page can render on its own.&lt;/p&gt;

&lt;p&gt;For the 404 page, you’ll just wrap a few lines with your &lt;code&gt;Layout&lt;/code&gt; component and call it a day:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../layouts/default&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;NotFoundPage&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Layout&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;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;NOT&lt;/span&gt; &lt;span class="nx"&gt;FOUND&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&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="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;just&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;doesn&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="nx"&gt;exist&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;sadness&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&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;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;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;NotFoundPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Preview your production site
&lt;/h2&gt;

&lt;p&gt;Running &lt;code&gt;gatsby develop&lt;/code&gt; lets you run a development-friendly version of your site, with neat features like hot-reloading of components when you make changes.&lt;/p&gt;

&lt;p&gt;To preview what your site will look like in production, you can use the &lt;code&gt;gatsby build&lt;/code&gt; and &lt;code&gt;gatsby serve&lt;/code&gt; commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After running &lt;code&gt;gatsby build&lt;/code&gt;, your website will be compiled and saved into a folder named &lt;code&gt;public&lt;/code&gt; at the top of your project.&lt;/li&gt;
&lt;li&gt;After running &lt;code&gt;gatsby serve&lt;/code&gt;, you can visit your production preview at &lt;code&gt;localhost:9000&lt;/code&gt; in your browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deploy your fancy new site to Netlify
&lt;/h2&gt;

&lt;p&gt;Now that your project is completed, it’s time to get it online! By using Gatsby, you’ll be circumventing TakeShape’s built-in static site generator, so you will need to set up your deployment system manually using a combination of Netlify’s continuous integration features and TakeShape’s webhooks functionality.&lt;/p&gt;

&lt;p&gt;First make sure that your project is hosted in a remote Git repository, like on GitHub. Then create a &lt;strong&gt;New site from Git&lt;/strong&gt; from the &lt;a href="https://app.netlify.com/account/sites" rel="noopener noreferrer"&gt;Netlify sites page&lt;/a&gt;. Authorize Netlify to access your project’s repository, then use the default build configuration. Netlify should automatically recognize that you’re using Gatsby as your static site generator and configure your build settings correctly. Then click &lt;strong&gt;Deploy Site&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your first Deploy should fail. That’s ok! You haven’t added your &lt;code&gt;TAKESHAPE_PROJECT&lt;/code&gt; and &lt;code&gt;TAKESHAPE_TOKEN&lt;/code&gt; settings to your environment in TakeShape, so you should expect it to fail.&lt;/p&gt;

&lt;p&gt;To fix this, go to your Netlify site’s settings and go to the “Build &amp;amp; Deploy” section. From there, you can edit your “Build environment variables” to securely add your TakeShape credentials. Click &lt;strong&gt;Edit variables&lt;/strong&gt; and then add your variables for &lt;code&gt;TAKESHAPE_PROJECT&lt;/code&gt; and &lt;code&gt;TAKESHAPE_TOKEN&lt;/code&gt;. Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then, go to your site’s Deploy section and click &lt;strong&gt;Trigger deploy&lt;/strong&gt;. You’ll watch your deployment script run and log messages as it goes. At the end, you should see success messages and finally a declaration that your “Site is live”! Congrats!!! 🎉 If you go back to your site’s overview, you should see a link to your newly live site.&lt;/p&gt;

&lt;p&gt;Finally you’ll want to set up a Build webhook &lt;em&gt;(Webhooks are available on all paid TakeShape plans)&lt;/em&gt; so that you can tell Netlify to rebuild your site when you create, update, or delete your content in TakeShape. Back in your Netlify site’s “Build &amp;amp; Deploy” settings, look for the section labelled “Build hooks”. Click &lt;strong&gt;Add build hook&lt;/strong&gt;, give it a name like “TakeShape”, click &lt;strong&gt;Save&lt;/strong&gt;, and then copy the URL that gets created for you.&lt;/p&gt;

&lt;p&gt;Then, in TakeShape, navigate to your project’s webhook settings in &lt;strong&gt;Project Settings &amp;gt; Webhooks&lt;/strong&gt;. Configure a new webhook so that the URL you just copied is the &lt;strong&gt;Webhook URL&lt;/strong&gt; and the &lt;strong&gt;Resources&lt;/strong&gt; that trigger it are &lt;code&gt;Content: *&lt;/code&gt;. And make sure you check the Create, Update, and Delete actions. Leave the &lt;strong&gt;Secret&lt;/strong&gt; field blank and click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, whenever you create a new content object, update an existing one, or delete a content object, it’ll trigger a new build of your site in Netlify. This way, your site is always up-to-date with your TakeShape project.&lt;/p&gt;

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

&lt;p&gt;If you’ve made it this far, congratulations! You dove head-first into the JAMstack and survived. Hopefully, you now have a strong understanding of the power of a configurable CMS, an automatically-generated GraphQL API, and a powerful React-powered static site. JAMstack is the future of web development and you’re now at the cutting edge.&lt;/p&gt;

&lt;p&gt;If you have any feedback, comments, or questions on our series, don’t hesitate to reach out. Your feedback is always welcome through our in-app live chat or via &lt;a href="//mailto:support@takeshape.io"&gt;support@takeshape.io&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested In Headless CMS For Gatsby.js?
&lt;/h2&gt;

&lt;p&gt;TakeShape is a headless GraphQL CMS that makes building JAMstack with Gatsby easier. At TakeShape we're building the best tools for managing content possible for the most creative designers and developers. Our project templates, make it easy to get started. Plus, pricing is downright affordable. &lt;a href="https://app.takeshape.io/signup" rel="noopener noreferrer"&gt;Sign up for a free account&lt;/a&gt; and spend more time being creative!&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>tutorial</category>
      <category>learning</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🍯 Two Awesome Days at JAMstack Conf 2018!</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Thu, 01 Nov 2018 18:54:05 +0000</pubDate>
      <link>https://forem.com/takeshape/two-days-at-jamstack-conf-2018-3kg4</link>
      <guid>https://forem.com/takeshape/two-days-at-jamstack-conf-2018-3kg4</guid>
      <description>&lt;p&gt;My co-founder at &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;TakeShape&lt;/a&gt; and I spent 2 days at &lt;a href="https://jamstackconf.com" rel="noopener noreferrer"&gt;JAMstack Conf 2018&lt;/a&gt; in San Francisco. Here's my debrief of the event. &lt;/p&gt;

&lt;p&gt;TLDR: We're very much looking forward to JAMstack conf 2019! Did you go to JAMstack Conf? I'd love to hear about other people's experiences in the comments!&lt;/p&gt;

&lt;p&gt;What is the JAMstack 🍯? The JAMstack is JavaScript, APIs and Markup. The short of it is  the JAMstack is probably what you've been doing for a while, just with an awesome name!&lt;/p&gt;

&lt;p&gt;The first time I heard the term JAMstack was probably in 2015 reading &lt;a href="https://www.netlify.com/blog/2015/11/16/what-is-the-jamstack/" rel="noopener noreferrer"&gt;"What is the JAMstack?"&lt;/a&gt;, on Netlify's blog. A few weeks prior Matt Biilmann, founder of Netlify wrote a piece for Smashing Magazine titled &lt;a href="https://www.smashingmagazine.com/2015/11/modern-static-website-generators-next-big-thing/" rel="noopener noreferrer"&gt;"Why Static Site Generators Are The Next Big Thing"&lt;/a&gt; that explored the ideas behind JAMstack without using the word itself. On stage at JAMstack Conf 2018, Matt talked about where the JAMstack name came from. Like most great ideas, turns out it was a few friends sitting around their living room tossing around ideas.&lt;/p&gt;

&lt;p&gt;I'm a front-end developer by trade and I fell in love with the term JAMstack the moment I heard it. As a front-end developer JAMstack is empowering. It gives you a framework to take your ideas all the way from front-end to what used to be the domain of the backend-developer. During his talk at JAMstack conf a very animated and energetic Chris Coyier proclaimed "I'm a front end developer and I don't need anybody...!" Bam!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Conference
&lt;/h2&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1057015887654412288-917" src="https://platform.twitter.com/embed/Tweet.html?id=1057015887654412288"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1057015887654412288-917');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1057015887654412288&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Attending the JAMstack conference felt, as &lt;a href="https://www.budparr.com/" rel="noopener noreferrer"&gt;Bud Parr&lt;/a&gt; from &lt;a href="https://www.thenewdynamic.org/" rel="noopener noreferrer"&gt;The New Dynamic&lt;/a&gt; put it, like coming home. Netlify may have coined the term, but it's clear that a community is growing around the JAMstack. The conference was perfectly sized, around 150 people attended the Agency day on day 1 and 300 people attended the main track on day 2. It felt like you could meet everyone, and I think I tried to do just that. There was a high level of camaraderie and friendliness all around and everyone was friendly and eager to learn. &lt;a href="https://twitter.com/philhawksworth" rel="noopener noreferrer"&gt;Phil Hawkwsorth&lt;/a&gt;, M.C. for the event, put together an incredible lineup of speakers. I really can't say enough good things the experience. I hope Netlify will repeat the event next year and I can't wait to see how the ideas presented at the conference start to spread.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1057786682609672193-853" src="https://platform.twitter.com/embed/Tweet.html?id=1057786682609672193"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1057786682609672193-853');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1057786682609672193&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  Hot Takeaways
&lt;/h2&gt;

&lt;p&gt;My quick takeaways 🔥 from each talk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 1 - Agency Day
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Matt Biilmann, How we talk about the JAMstack&lt;/strong&gt;&lt;br&gt;
JAMstack is graduating into the common developer vernacular.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thomas Reynolds, The 3 types of clients you’ll need to convince&lt;/strong&gt;&lt;br&gt;
&lt;a href="http://blogs.microsoft.co.il/gadib/2010/10/11/technical-design-document-template/" rel="noopener noreferrer"&gt;Technical Design Document Template from Microsoft&lt;/a&gt;. This would have been handy to have in my agency life.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tim Fogarty, Finding the best home for your data&lt;/strong&gt;&lt;br&gt;
Don't bother standing up your own DB infrastructure, even on AWS, unless it's somehow going to be a differentiator. Learn from &lt;a href="https://about.gitlab.com/2017/02/10/postmortem-of-database-outage-of-january-31/" rel="noopener noreferrer"&gt;Gitlab's mistakes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Taylor Gilbert, 3 truths that you can bet the next 5 years on&lt;/strong&gt;&lt;br&gt;
Holy moly a lot of big agencies are getting into JAMstack. 50% of the agencies in Gartner's magic quadrant are adopting JAMstack approaches over traditional monolithic stacks in order to deliver "best in class service stacks".&lt;/p&gt;

&lt;p&gt;Great quote form Jeff Bezos:&lt;br&gt;
"I very frequently get the question: 'What's going to change in the next 10 years?' And that is a very interesting question; it's a very common one. I almost never get the question: 'What's not going to change in the next 10 years?."&lt;/p&gt;
&lt;h3&gt;
  
  
  Day 1 - Lightning Talks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Zoltan Olah, Turning design into code the painless way&lt;/strong&gt;&lt;br&gt;
Check out adding &lt;a href="https://storybook.js.org/" rel="noopener noreferrer"&gt;Storybook&lt;/a&gt; for our &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;TakeShape&lt;/a&gt; product development process&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eric Gardner, Building books from static sites: Digital (and print) publishing with the JAMstack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How can I get my fiancé to use &lt;a href="https://github.com/gettypubs/quire" rel="noopener noreferrer"&gt;Quire&lt;/a&gt; to publish her dissertation in Art History? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tanmai Gopal, How to setup production-ready automation for database change to JAMstack deployment&lt;/strong&gt;&lt;br&gt;
Note to self, next time I present to a group, be more high energy and try to come up with more witty punch lines. Also check out &lt;a href="https://hasura.io/" rel="noopener noreferrer"&gt;Hasura&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bud Parr, Go Go Hugo!&lt;/strong&gt;&lt;br&gt;
How is Hugo so fast?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steve Gardner, Make more pointless things&lt;/strong&gt;&lt;br&gt;
Practice doing lots of little creative projects. You get the benefit of compounding interest on your knowledge and skills. And you gain confidence to tackle the larger projects that once seemed daunting. This talk was soo well paced and crammed so much into 10 minutes. It made me want to go out and start making things right away. &lt;/p&gt;
&lt;h3&gt;
  
  
  Day 2 - Main Track
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Monica Dinculescu, Bet you didn’t think your browser could do that&lt;/strong&gt;&lt;br&gt;
Holy Moly IBM plex looks great! &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1057331736068014080-406" src="https://platform.twitter.com/embed/Tweet.html?id=1057331736068014080"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1057331736068014080-406');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1057331736068014080&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prateek Bahatnagar, Supercharged PWAs with Preact-cli&lt;/strong&gt;&lt;br&gt;
Lots of opportunity to optimizing TakeShape's web client. Gotta reach for that 💯 on Lighthouse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jessica Lord, Everyone is a Developer&lt;/strong&gt;&lt;br&gt;
Reminder to read "How to Design Programs" as a bedtime story to my future child.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chris Coyier, The All-Powerful Front-End Developer&lt;/strong&gt;&lt;br&gt;
⚡⚡⚡⚡⚡ SO MUCH ENERGY ⚡⚡⚡⚡ For me this talk was the most empowering of the day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simona Cotin, Build scalable APIs using GraphQL and Serverless&lt;/strong&gt;&lt;br&gt;
Why use GraphQL? Increases performance. Query only the data you need. Increased flexibility. Tooling is fantastic. GraphQL helps you create single interface over many Serverless functions. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quincy Larson, How freeCodeCamp.org serves millions of learners using the JAMstack&lt;/strong&gt;&lt;br&gt;
Learned to code in his 30s and now teaches millions of people to code all over the world for free. I'm not doing nearly enough with my life.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wes Bos &amp;amp; Scott Tolinski, Syntax FM Live&lt;/strong&gt;&lt;br&gt;
Live podcasts are so much fun! &lt;/p&gt;

&lt;h2&gt;
  
  
  How To Know If You're Already On The JAMstack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You building things for the web?&lt;/li&gt;
&lt;li&gt;You crave perf.&lt;/li&gt;
&lt;li&gt;You're building amazing dynamic interfaces with vanilla JavaScript / react / vue&lt;/li&gt;
&lt;li&gt;You agree with the following statement: Pre-rendering markup and putting it on a CDN is awesome
You know that using static site generator doesn't mean building a boring experience. It means you get to build a kick ass site and not deal with a bunch of baloney like how to set up a LAMP stack&lt;/li&gt;
&lt;li&gt;You laugh at the idea of spinning up an EC2 instance and use Serverless functions like a civilized person.&lt;/li&gt;
&lt;li&gt;Bonus points - When you hear headless CMS you think "Sweet, no more WordPress!", instead of thinking of a horseman.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The JAMstack site has a &lt;a href="https://jamstack.org/" rel="noopener noreferrer"&gt;less silly definition&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm A JAMstack Believer
&lt;/h2&gt;

&lt;p&gt;I've bought into the benefits of JAMstack. I want sites to be fast. I want to be able to assemble projects using best-in-class services, not just what a particular platform supports. I want to spend more time creating and less time dealing with backends. I think enabling more people to create better things is how we grow an even more interconnected community. I believe in the JAMstack so much that I co-founded a company, &lt;a href="//takeshape.io"&gt;TakeShape&lt;/a&gt; a headless GraphQL CMS, to help people create more things with a JAMstack approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking For A Headless CMS?
&lt;/h2&gt;

&lt;p&gt;TakeShape is a headless GraphQL CMS and static site generator for building JAMstack websites. At TakeShape we're building the best tools possible for managing content, for the most creative designers and developers.&lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;Sign up for a free account&lt;/a&gt; and spend more time being creative with the JAMstack!&lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>netlify</category>
      <category>conferences</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Publish A JAMstack Site To Netlify In Less Than 2 Minutes With TakeShape</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Mon, 29 Oct 2018 10:48:40 +0000</pubDate>
      <link>https://forem.com/takeshape/publish-a-jamstack-site-to-netlify-in-less-than-2-minutes-with-takeshape-4f97</link>
      <guid>https://forem.com/takeshape/publish-a-jamstack-site-to-netlify-in-less-than-2-minutes-with-takeshape-4f97</guid>
      <description>&lt;h2&gt;
  
  
  In part 3 of this 4 part series, you'll learn how to publish a static site to Netlify
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This is part 3 of a 4 part series about building a portfolio with Takeshape. Check out &lt;a href="https://www.takeshape.io/articles/how-to-build-a-design-portfolio-with-takeshape/"&gt;part 1&lt;/a&gt; to learn how to model and create content. &lt;a href="https://www.takeshape.io/articles/how-to-build-a-jamstack-website-with-takeshape/"&gt;Part 2&lt;/a&gt; shows you how to create a static site that loads data from TakeShape. In part 4 (coming soon) you’ll extend your skills even further and learn how to build a React-based static site with TakeShape and Gatsby.js.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you’ve been following along with the series, you already have a flexible content model in TakeShape and a static site that works with it. Now, you’ll learn how to use &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt; with TakeShape to deploy your live site in as few as 2 minutes. Here's a &lt;a href="https://shape-portfolio.takeshapesampleproject.com/"&gt;demo&lt;/a&gt; of what you'll be deploying. With 1-click integration, TakeShape makes it easy to get your new site live, running on a CDN and using HTTPS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you’re just joining, don’t worry. You can catch up quickly by &lt;a href="https://app.takeshape.io/signup"&gt;signing up for a free TakeShape account&lt;/a&gt;, creating a template “Shape Portfolio” project, and cloning the &lt;a href="https://github.com/takeshape/takeshape-samples"&gt;“takeshape-samples” repository&lt;/a&gt; from GitHub. After creating your template project, open your terminal to clone and access the sample repo with the command &lt;code&gt;git clone https://github.com/takeshape/takeshape-samples.git takeshape-samples &amp;amp;&amp;amp; cd takeshape-samples/shape-portfolio&lt;/code&gt;. Now we’re all on the same page!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TakeShape and Netlify go together like Peanut Butter and Jelly
&lt;/h2&gt;

&lt;p&gt;Before getting started with the rest of the walkthrough, here’s a quick primer on why TakeShape and Netlify make such a delicious JAMstack sandwich with your content at the center.&lt;/p&gt;

&lt;p&gt;Netlify is a powerful and easy-to-use platform for deploying, maintaining, and upgrading your static site. Out of the box, Netlify provides robust hosting, continuous integration tools, and default security with automatic HTTPS. As your site grows, Netlify helps remove many of the obstacles static sites face early on. They’ll provide you with endpoints for form submissions, serverless functions, and even let you manage user identities. Put simply, they give you all the pluses of going static with none of the minuses.&lt;/p&gt;

&lt;p&gt;Even better, TakeShape is built to integrate directly with Netlify. With a 1-click integration, you can quickly set up a static site publishing target for your TakeShape project and get your new project live within minutes. With TakeShape handling your content and Netlify hosting your site, you’re free to focus on what matters: your content and your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect your TakeShape project to Netlify
&lt;/h2&gt;

&lt;p&gt;Now, you’ll put these bold claims to the test by integrating your TakeShape project with Netlify. You’ll quickly see that it lives up to the hype!&lt;/p&gt;

&lt;p&gt;Start by either logging in or signing up for an account with &lt;a href="https://app.netlify.com/signup"&gt;Netlify&lt;/a&gt;. You can do this for free and even use your existing GitHub, GitLab, or BitBucket account.&lt;/p&gt;

&lt;p&gt;TakeShape already provides some &lt;a href="https://www.takeshape.io/docs/configuring-netlify/"&gt;comprehensive instructions to configure Netlify on your project&lt;/a&gt;, so we’ll keep this brief.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8zgyi50h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7adna9ry865w69ok3ue7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8zgyi50h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7adna9ry865w69ok3ue7.gif" alt="TakeShape integration with Netlify"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, go to Project Settings &amp;gt; Integrations and link your Netlify account with your TakeShape project. Then, go to Static Sites and create a new static site. Name it whatever is appropriate and choose Netlify as the provider. Then, for the destination, choose + Create a New Static Site. Both the “Name” and “Password” fields are optional. If you don’t choose a name Netlify will generate one for you automatically. You can edit the name and password later from the Netlify admin. Finally, click Save.&lt;/p&gt;

&lt;p&gt;Poof! Wasn’t that easy?&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy your static site to Netlify
&lt;/h2&gt;

&lt;p&gt;Your site templates will make the following journey:&lt;/p&gt;

&lt;p&gt;Local Dev Environment &amp;gt; TakeShape Environment &amp;gt; Netlify Hosting&lt;/p&gt;

&lt;p&gt;Now that you’ve got TakeShape and Netlify talking to one another, you’re all ready to deploy your site using the CLI. Deploying your site will upload your templates and configuration to TakeShape’s cloud environment so that you can build and publish your project before uploading it to Netlify.&lt;/p&gt;

&lt;p&gt;In your terminal, &lt;code&gt;cd&lt;/code&gt; to the folder with your TakeShape project on your local machine. Next, you’ll re-initialize your TakeShape project with &lt;code&gt;npm run init&lt;/code&gt;, input your TakeShape username and password, and choose your newly configured “Netlify” static site as the deploy destination. You should see the newly generated files &lt;code&gt;.graphqlrc&lt;/code&gt;, &lt;code&gt;.tsgrc&lt;/code&gt;, and &lt;code&gt;graphql.config.json&lt;/code&gt;, as well as a success message and a warning to not add these files to your version control.&lt;/p&gt;

&lt;p&gt;Now, for the moment of truth. Run &lt;code&gt;npm run deploy&lt;/code&gt;. If everything goes okay, you’ll see a success message. If things don’t go as expected read the output of the error message in the terminal closely to try to debug the problem. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Bonus points: Set up continuous integration with Netlify&lt;/strong&gt;&lt;br&gt;
Since Netlify has built-in continuous integration, it’s possible to set up your site to automatically deploy when you push new commits to a branch if your project lives in GitHub, GitLab, or BitBucket. TakeShape has &lt;a href="https://www.takeshape.io/docs/continuous-deployment-of-templates/"&gt;provided a simple guide&lt;/a&gt; to get that set up and working, and it can really be a boost to your productivity when building out your site.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Publish from the web
&lt;/h2&gt;

&lt;p&gt;When you deploy your site from the CLI, TakeShape will publish it once automatically. If you add or change your project’s content, you can publish the changes right from the TakeShape web client by selecting “Publish [your static site name] in the project menu dropdown.&lt;/p&gt;

&lt;p&gt;From the project menu, when you select “Publish Netlify,” TakeShape will start building a new version of your project and uploading it to Netlify. You’ll see a success message within a second or two.&lt;/p&gt;

&lt;p&gt;And that’s all there is to it! As you can see, TakeShape and Netlify compliment one another beautifully. In just a few minutes, you can have a secure, fast, and fully-customizable static site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Really, we could stop right here, since you’ve got a static website working beautifully with TakeShape and Netlify. But in the final part of our walkthrough, we’re going to kick it up a notch, as Emeril Lagasse says. We’ll show you how to take your static site to the next level. You’ll unlock new levels of power and flexibility by using Gatsby.js as your static site generator to build your portfolio using React components. So exciting!&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested in CMS For Static Websites?
&lt;/h2&gt;

&lt;p&gt;TakeShape is a headless GraphQL CMS and static site generator for building JAMstack websites. At TakeShape we're building the best tools for managing content possible for the most creative designers and developers. Our project templates, make it easy to get started. Plus, pricing is downright affordable. &lt;a href="https://app.takeshape.io/signup"&gt;Sign up for a free account&lt;/a&gt; and spend more time being creative!&lt;/p&gt;

</description>
      <category>netlify</category>
      <category>tutorial</category>
      <category>learning</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Build A JAMstack Website With TakeShape</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Wed, 24 Oct 2018 21:17:26 +0000</pubDate>
      <link>https://forem.com/takeshape/how-to-build-a-jamstack-website-with-takeshape-35l</link>
      <guid>https://forem.com/takeshape/how-to-build-a-jamstack-website-with-takeshape-35l</guid>
      <description>&lt;h2&gt;
  
  
  In part 2 of this 4 part series, you'll learn how to use a headless cms to build a static site.
&lt;/h2&gt;

&lt;p&gt;This is part 2 of the 4 part series. Check out part 1 to get an introduction to &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;TakeShape&lt;/a&gt; and learn content modeling and content creation. In part 3 (coming soon) you’ll learn how to deploy your static site to Netlify. In part 4 (coming soon) you’ll extend your skills even further and learn how to use TakeShape with Gatsby.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4g8kx0b0z5qt62u86cw5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4g8kx0b0z5qt62u86cw5.png" alt="A screenshot of the JAMstack site you’ll be building."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In part 1 you learned how to model and create content and making it available through TakeShape’s GraphQL API. Now you’ll learn how to use TakeShape’s static site generator in combination with that API to quickly create a JAMstack website. You’ll create and configure a TakeShape static site on your local machine, write GraphQL query files and use data returned from those queries in HTML templates.&lt;/p&gt;

&lt;p&gt;If you want to skip setting up your static site from scratch, you can grab the “&lt;a href="https://shape-portfolio.takeshapesampleproject.com/" rel="noopener noreferrer"&gt;Shape Portfolio&lt;/a&gt;” sample template as a starting point. Simply run the command &lt;code&gt;git clone https://github.com/takeshape/takeshape-samples.git &amp;amp;&amp;amp; cd takeshape-samples/shape-portfolio&lt;/code&gt;. This will download a static site &lt;a href="https://github.com/takeshape/takeshape-samples" rel="noopener noreferrer"&gt;repo&lt;/a&gt; that’s pre-configured to work with the “Shape Portfolio” template in TakeShape. This repo has a more complex, styled, and scripted version of what we just built together. It might give you some inspiration and guidance on where to take your portfolio next.&lt;/p&gt;

&lt;p&gt;If you decided to stay, we’ll be building that same &lt;code&gt;shape-portfolio&lt;/code&gt; static site from scratch so you can learn how it works. Ready, set, go!&lt;/p&gt;

&lt;h3&gt;
  
  
  Hello Portfolio
&lt;/h3&gt;

&lt;p&gt;You’re going to start by cloning the &lt;code&gt;blank-project&lt;/code&gt; template from Github, this will provide you with a &lt;a href="https://github.com/takeshape/takeshape-samples.git" rel="noopener noreferrer"&gt;bare-bones TakeShape setup&lt;/a&gt;. First, clone the repository to your computer, then copy the blank-project out into a new folder, and finally remove the cloned repo since you don’t need anything else from it. In your terminal, it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; git clone https://github.com/takeshape/takeshape-samples.git
&amp;gt; cp -r takeshape-samples/blank-project/ shape-portfolio
&amp;gt; rm -rf takeshape-samples
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you’ll enter the newly copied project folder, install the required software needed to run the project with npm, and initialize it with the TakeShape configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; cd shape-portfolio
&amp;gt; npm install
&amp;gt; npm run init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;init&lt;/code&gt; will establish the connection between your local development environment and the TakeShape service. You’ll be prompted to make several sections to configure your environment. The first prompt will be for your TakeShape credentials. Input your TakeShape account email and password, then use the arrow keys to select your portfolio project. You’ll get a reminder about not having any sites set up yet (don’t worry, we’ll get to that in Part 3).&lt;/p&gt;

&lt;p&gt;The initialization creates two files, &lt;code&gt;.tsgrc&lt;/code&gt; and &lt;code&gt;graphql.config.json&lt;/code&gt;. These are already in your project’s &lt;code&gt;.gitignore&lt;/code&gt; file because you started with the blank-project template.&lt;/p&gt;

&lt;p&gt;You can now test that everything’s been set up correctly by running &lt;code&gt;npm start&lt;/code&gt;. If everything goes as expected, your default browser will open to &lt;code&gt;localhost:5000&lt;/code&gt; and display the blank-template page. Hooray! You’ve just run TakeShape from your local machine. Now it’s time to start hacking on your portfolio 🤓. If you get an error or aren’t able to load the site read any error messages that are output to the terminal to debug the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;By cloning the &lt;code&gt;blank-project&lt;/code&gt; template, you’ve been provided with some of the basic files and folders that TakeShape expects. We’ll explain a bit more about each of them now.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuration
&lt;/h4&gt;

&lt;p&gt;At the root of your project is a file called &lt;code&gt;tsg.yml&lt;/code&gt;. It holds the configuration for your project and it’s the best place to start. Here’s what’s in &lt;code&gt;tsg.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;templatePath: src/templates
staticPath: static
buildPath: build

routes:
  homepage:
    path: /
    template: pages/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;At the top is the &lt;code&gt;templatePath&lt;/code&gt; variable, which tells TakeShape where to look for template files when building your project.&lt;/li&gt;
&lt;li&gt;Next is the &lt;code&gt;staticPath&lt;/code&gt; variable, which tells TakeShape where to look for files like stylesheets, scripts, and static images like favicons.&lt;/li&gt;
&lt;li&gt;After that is the &lt;code&gt;buildPath&lt;/code&gt; variable, which is where TakeShape will place your project after it’s been built.&lt;/li&gt;
&lt;li&gt;Finally, there’s the &lt;code&gt;routes&lt;/code&gt; variable. Each child of this variables configures the routing rules of your project. Right now we only have the &lt;code&gt;homepage&lt;/code&gt; route, which specifies the routing path (the index path, in this case) and what template file the route should use. Templates are all relative to the &lt;code&gt;templatePath&lt;/code&gt; set at the top of the file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are more complex ways to build routes, including dynamic variables that comes from the content you’ve created in TakeShape. We’ll get to this in a moment. First, let’s take a look at the templates you’re going to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Template Files
&lt;/h3&gt;

&lt;p&gt;By default, TakeShape uses the &lt;a href="https://mozilla.github.io/nunjucks/" rel="noopener noreferrer"&gt;Nunjucks&lt;/a&gt; templating system.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;src/templates&lt;/code&gt; folder contains three starter subdirectories: &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;layouts&lt;/code&gt;, &lt;code&gt;pages&lt;/code&gt;. &lt;code&gt;data&lt;/code&gt; contains GraphQL query files that retrieve content from the TakeShape API. &lt;code&gt;pages&lt;/code&gt; contains individual unique page templates. &lt;code&gt;layouts&lt;/code&gt; contains a base template that other templates extend. Inside &lt;code&gt;layouts&lt;/code&gt; is a starter layout template called &lt;code&gt;default.html&lt;/code&gt;, which looks like this:&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;!doctype html&amp;gt;

&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Blank Project - TakeShape&amp;lt;/title&amp;gt;

  &amp;lt;meta charset="utf-8"&amp;gt;

  &amp;lt;link rel="stylesheet" href="/stylesheets/main.css"/&amp;gt;
  &amp;lt;link rel="author" href="humans.txt"/&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;

&amp;lt;div class="main"&amp;gt;
  {% block content %}{% endblock %}
&amp;lt;/div&amp;gt;

&amp;lt;script src="/javascripts/main.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this provides the basis for other pages to wrap themselves in the layout by using Nunjuck’s extend functionality. Extending is accomplished by using the using &lt;code&gt;{% extends "layouts/default.html" %}&lt;/code&gt; and &lt;code&gt;{% block %}&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;pages/index.html&lt;/code&gt; you can see how this template extends the default layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% extends "layouts/default.html" %}

{% block content %}
  &amp;lt;h1&amp;gt;Blank Project Template For TakeShape&amp;lt;/h1&amp;gt;
{% endblock %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these basic foundations, you can build plenty of pages with minimal repetition.&lt;/p&gt;

&lt;h4&gt;
  
  
  Static Files
&lt;/h4&gt;

&lt;p&gt;Finally, we’ll take a quick look at static files like stylesheets and scripts. The starting &lt;code&gt;default.html&lt;/code&gt; template above already links to the files &lt;code&gt;/stylesheets/main.css&lt;/code&gt; and &lt;code&gt;/javascripts/main.js&lt;/code&gt;. You’ll find these files in the top-level &lt;code&gt;static&lt;/code&gt; directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building your portfolio
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Homepage
&lt;/h4&gt;

&lt;p&gt;Now that you know how everything fits together, you can start customizing your homepage to create an amazing portfolio!&lt;/p&gt;

&lt;p&gt;First, you’ll want to display your projects on your homepage. To do this, you’ll need to add some data to the homepage route, write a query, and then render the data on the homepage. To add data to the route, you’ll update your homepage route configuration in &lt;code&gt;tag.yml&lt;/code&gt; to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;routes:
  homepage:
    path: /
    template: pages/index.html
    context: data/projects.graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a &lt;code&gt;projects.graphql&lt;/code&gt; file in the &lt;code&gt;src/templates/data&lt;/code&gt; directory. In this file, you’re going to craft the query for your project data that’s sent to the TakeShape API.  As long as you set up your Project content type following the pattern in Part 1, your file should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
 projects: getProjectList {
   items {
     name
     coverImage {
       path
     }
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can use &lt;code&gt;projects&lt;/code&gt; as a variable in our homepage template in order to render a list of all projects on the homepage. In &lt;code&gt;pages/index.html&lt;/code&gt; you’ll update it to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% extends "layouts/default.html" %}

{% block content %}
&amp;lt;ul&amp;gt;
  {% for project in projects.items %}
  &amp;lt;li&amp;gt;
      &amp;lt;img src="{{project.coverImage.path|image({h: 200, w: 300, fit: 'crop'})}}"&amp;gt;
      &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;{{project.name}}&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;/li&amp;gt;
  {% endfor %}
&amp;lt;/ul&amp;gt;
{% endblock %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the cover image, note the &lt;code&gt;image&lt;/code&gt; filter being applied to the image’s path. TakeShape users get to host their images on &lt;a href="https://www.imgix.com/" rel="noopener noreferrer"&gt;imgix&lt;/a&gt;, an amazing and powerful image CDN, for free! The &lt;code&gt;image&lt;/code&gt; filter is a &lt;a href="https://www.takeshape.io/docs/template-tags/" rel="noopener noreferrer"&gt;special TakeShape filter&lt;/a&gt; that accepts IMGIX filter parameters and returns the imgix URL for the image. We’ve set a custom height and width on the image and we’ve told imgix to crop the image to fit these dimensions. All the potential options are listed on &lt;a href="https://docs.imgix.com/apis/url" rel="noopener noreferrer"&gt;imgix’s comprehensive API documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Standalone project pages
&lt;/h4&gt;

&lt;p&gt;Next, you’ll want to create standalone pages for your projects so that you can provide more detail about each one and link to projects directly.&lt;/p&gt;

&lt;p&gt;To get started, update your &lt;code&gt;tsg.yml&lt;/code&gt; configuration with a new route for project pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  project:
    path: /projects/:name/
    template: pages/project.html
    paginate:
      data: data/projects.graphql
      itemName: project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a little more complex than our last route, so let’s break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;path&lt;/code&gt; uses the variable &lt;code&gt;:name&lt;/code&gt; in order to render a unique URL for each project page. This variable comes right from the query we’re using in the &lt;code&gt;paginate&lt;/code&gt; variable.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;paginate&lt;/code&gt; tells TakeShape how to split up the data from the &lt;code&gt;projects.graphql&lt;/code&gt; query we created earlier into individual pages. In this case, each &lt;code&gt;item&lt;/code&gt; in the query will get its own page. &lt;code&gt;itemName&lt;/code&gt; sets the variable that refers to each paginated item. In this case, we’ll access data from a variable named &lt;code&gt;project&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, you’ll want to add a few more fields to the &lt;code&gt;projects.graphql&lt;/code&gt; query so that you can present more information about each project on its standalone page. Update your query to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  projects: getProjectList {
    items {
      name
      startDate
      endDate
      coverImage {
        path
      }
      descriptionHtml
      client {
        name
        url
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty straightforward! Think you’re getting the hang of building a site in TakeShape? Remember, you can explore the API for your entire project in TakeShape’s web interface. It’s really handy when writing queries yourself.&lt;/p&gt;

&lt;p&gt;Now, you can create the &lt;code&gt;pages/project.html&lt;/code&gt; template to render out the project data into HTML. Here’s what that will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% extends "layouts/default.html" %}

{% block content %}
&amp;lt;article class="project"&amp;gt;
  &amp;lt;header&amp;gt;
    &amp;lt;img class="project__cover-image" src="{{project.coverImage.path|image({h: 600, w: 1200, fit: 'crop'})}}"&amp;gt;
    &amp;lt;h1&amp;gt;{{project.name}}&amp;lt;/h1&amp;gt;
    &amp;lt;div class="project__metadata"&amp;gt;
    &amp;lt;p&amp;gt;{{project.startDate|date('YYYY')}}{% if project.endDate %} – {{project.endDate|date('YYYY')}}{% endif %}&amp;lt;/p&amp;gt;
    {% if project.client %}
    &amp;lt;p&amp;gt;&amp;lt;a href="{{project.client.url}}"&amp;gt;{{project.client.name}}&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
    {% endif %}
    &amp;lt;/div&amp;gt;
  &amp;lt;/header&amp;gt;
  &amp;lt;div class="project__description"&amp;gt;{{project.descriptionHtml|safe}}&amp;lt;/div&amp;gt;
&amp;lt;/article&amp;gt;
{% endblock %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty straightforward, too! Notice how the built-in TakeShape &lt;code&gt;date&lt;/code&gt; filter is being used to format the start and end dates of your project so only the year is displayed. Also, notice that the &lt;code&gt;safe&lt;/code&gt; filter must be applied to the project description. This is because it’s output from the TakeShape API as raw HTML.&lt;/p&gt;

&lt;p&gt;Now that each of your projects has a page, you want to be able to link to individual projects from your homepage. On the homepage template, wrap each project list item with an anchor tag &lt;code&gt;&amp;lt;a href="{{project|route('project')}}"&amp;gt;&lt;/code&gt;. It should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% extends "layouts/default.html" %}

{% block content %}
&amp;lt;ul&amp;gt;
  {% for project in projects.items %}
  &amp;lt;li&amp;gt;
    &amp;lt;a href="{{project|route('project')}}" title="{{project.name}}"&amp;gt;
    &amp;lt;img src="{{project.coverImage.path|image({h: 200, w: 300, fit: 'crop'})}}"&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;{{project.name}}&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;/a&amp;gt;
  &amp;lt;/li&amp;gt;
  {% endfor %}
&amp;lt;/ul&amp;gt;
{% endblock %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;route&lt;/code&gt; is another special TakeShape filter. If you have a route defined for an object, like the one that defined a dynamic path for the project pages, then the &lt;code&gt;route&lt;/code&gt; filter will return the route for that item. It’s pretty handy! Just refer to the name of the route as it appears in your &lt;code&gt;tsg.yml&lt;/code&gt; and you’ll be good to go!&lt;/p&gt;

&lt;p&gt;Now, if you run &lt;code&gt;npm start&lt;/code&gt; in your terminal, the website should build successfully. You will see a homepage with a list of your projects and you should be able to click through to each one.&lt;/p&gt;

&lt;p&gt;For a next step, you can try creating an About page using your biography, or a page that lists all of your clients. Make sure to check out TakeShape’s documentation if you get stuck writing your configuration or templates.&lt;/p&gt;

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

&lt;p&gt;In part 3 we’ll take the static site you just created and deploy it to Netlify! In just a few steps, you’ll be able to deploy your site to Netlify’s CDN and host your page on a secure HTTPS connection. How cool is that?&lt;/p&gt;

&lt;p&gt;Until then, keep hacking!&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested in JAMstack CMS?
&lt;/h2&gt;

&lt;p&gt;JavaScript, APIs, and Markup, are the JAMStack. &lt;a href="https://www.takeshape.io/" rel="noopener noreferrer"&gt;TakeShape&lt;/a&gt; is a headless GraphQL CMS and static site generator for building JAMstack websites. At TakeShape we're committed to building the best CMS tools possible for the most creative designers and developers. With our project templates, it's easy to get started. Plus, pricing is flexible and affordable. &lt;a href="https://app.takeshape.io/signup" rel="noopener noreferrer"&gt;Sign up for a free account&lt;/a&gt; and spend more time being creative! &lt;/p&gt;

</description>
      <category>design</category>
      <category>tutorial</category>
      <category>learning</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Build A Design Portfolio With TakeShape</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Mon, 22 Oct 2018 14:46:46 +0000</pubDate>
      <link>https://forem.com/takeshape/how-to-build-a-design-portfolio-with-takeshape-4k7h</link>
      <guid>https://forem.com/takeshape/how-to-build-a-design-portfolio-with-takeshape-4k7h</guid>
      <description>&lt;h2&gt;
  
  
  In part 1 of this 4 part series, you'll learn to model and create content with &lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This is part 1 of a 4 part series. In part 1, we’ll start by creating a new project in TakeShape, modeling some basic content types, and then filling them in. In &lt;a href="https://www.takeshape.io/articles/how-to-build-a-jamstack-website-with-takeshape/"&gt;part 2&lt;/a&gt;, we’ll use TakeShape’s static site generator to create the HTML and CSS for the final website. In part 3 (coming soon) we’ll deploy the static site to Netlify. In part 4 (coming soon) you’ll extend your skills even further and learn how to use TakeShape with Gatsby.js.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EBfMITIe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4g8kx0b0z5qt62u86cw5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EBfMITIe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4g8kx0b0z5qt62u86cw5.png" alt="A screenshot of the designer portfolio site you’ll be building."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every web designer needs to have a great portfolio. While services like Squarespace make it easy to build a website using a cookie cutter template, the results all start to look the same. Yet when you design websites for a living, your portfolio should do more than simply catalogue your projects; it should itself demonstrate your craft.&lt;/p&gt;

&lt;p&gt;This is where &lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt; comes in! TakeShape is a flexible and easy to use tool that will let you focus on perfecting the unique design of your portfolio instead of wrestling with a server or debugging a database. With TakeShape you can perfect your portfolio in no time at all. Let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  Sign Up For A TakeShape Account
&lt;/h3&gt;

&lt;p&gt;If you don’t have a TakeShape account yet, start by &lt;a href="https://app.takeshape.io/signup"&gt;signing up&lt;/a&gt;. If you already have an account, &lt;a href="https://app.takeshape.io/login"&gt;log in&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create A New Blank TakeShape Project
&lt;/h3&gt;

&lt;p&gt;After you log in, create a new project using by selecting the Blank Project template. Then, give your new project a name.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note If you want to skip ahead to Part 2 and begin building the static website, you can choose the “Shape Portfolio” template instead. We’ll keep going from the blank project so you can see how it’s built.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X2MJygDf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0vup8dr24nnb83qzbsaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X2MJygDf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0vup8dr24nnb83qzbsaf.png" alt="TakeShape Create Project Screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create A Content Type
&lt;/h3&gt;

&lt;p&gt;Since the main purpose of your portfolio is to show off your design projects, we’ll start by creating a content type for them.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Add Content Type&lt;/strong&gt; button in the bottom left of the sidebar, just above your username. You’ll be taken to the “New Content Type” screen. Every content type has a few basic fields you need to fill in before you can start modeling your content.&lt;/p&gt;

&lt;p&gt;![TakeShape New Content Type Page](&lt;a href="https://thepracticaldev.s3.amazonaws.com/i/xkc9lbr05q6jpheb6eeh.png_"&gt;https://thepracticaldev.s3.amazonaws.com/i/xkc9lbr05q6jpheb6eeh.png_&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Title&lt;/em&gt; is the human-readable name of your content type. As a best practice, content type titles in TakeShape should be singular, not plural. We’ll name this type “Project”.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Name&lt;/em&gt; is how your content type will be named in TakeShape’s GraphQL API. Once you’ve given your content type a title, the name will fill in automatically. (But it can also be modified independently.)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Description&lt;/em&gt; is an optional, but extremely helpful, field—especially if your content type uses a generic name like “Project.”&lt;/li&gt;
&lt;li&gt;Finally, we’ll keep the &lt;em&gt;Annotation&lt;/em&gt; as “Multiple” since we want to include multiple projects in our portfolio. (We’ll create content types with other kinds of Annotation later on.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we can start modeling our Project content type in order to create the fields that every one of your projects will have. TakeShape’s drag-and-drop interface makes it easy to quickly add a variety of fields, creating a rich content type that’s exactly suited to your needs and can be updated if your needs change.&lt;/p&gt;

&lt;p&gt;To begin, add the following widgets from the left sidebar by dragging them to the drop zone and configuring them as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Line&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Name” and check the “Required” box. This needs to be a plain text string because later on you’ll use it to generate the URLs for each project page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Date&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Start Date” and check the “Required” box. This will allow you to sort your projects chronologically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Date&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “End Date.” This is an optional field, which will indicate whether you have completed your project or not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asset&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Cover Image.” This is an optional field, which will visually represent your project in lists and on the project page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block Canvas&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Description.” This is an optional field, which will allow you to compose your project’s description with rich text and formatting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u4vBiJQ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ps3e16oly7dtaupg7l3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u4vBiJQ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ps3e16oly7dtaupg7l3r.png" alt="Filled in TakeShape Content Type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve finished adding these widgets, click the &lt;strong&gt;Create Content Type&lt;/strong&gt; button to save your new type. After you save, you’ll be taken to the (empty) “Project” page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add The First Project To Your Portfolio
&lt;/h3&gt;

&lt;p&gt;Now you can add your projects to your portfolio! Click the green &lt;strong&gt;New Project&lt;/strong&gt; button at the top right. &lt;/p&gt;

&lt;p&gt;You’ll see that all the widgets you dragged into the content type now appear as fields ready to accept information. You can give your project a Name, a Start Date, an (optional) End Date, a Cover Image, and a longer Description.&lt;/p&gt;

&lt;p&gt;You’ll notice a few fields provide special interfaces for editing their information. For example, when setting the Start Date, a calendar-based date selector will appear. And when adding a Cover Image, the “Asset Library” will slide over from the right. You can upload new images by dragging-and-dropping them into this slide-over; then you can drag-and-drop these images from the “Asset Library” slide-over into the Cover Image field. Finally, the Description field has easy-to-use editing tools that appear when you need them, like when you highlight text or start a new paragraph.&lt;/p&gt;

&lt;p&gt;When you’re done adding content, click the green &lt;strong&gt;Save&lt;/strong&gt; button to save the content and return to the list of projects. If you click the down arrow &lt;strong&gt;[⌄]&lt;/strong&gt; next to &lt;strong&gt;Save&lt;/strong&gt;, you’ll see the option “Save and Continue,” which will save the content without returning to the list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create The About Page
&lt;/h3&gt;

&lt;p&gt;Next, we want to create an “About” page so you can share a little more information about yourself. &lt;/p&gt;

&lt;p&gt;Just like when you created the project content type, click the &lt;strong&gt;Add Content Type&lt;/strong&gt; button in the bottom left of the sidebar, just above your username. Give the content type a Title (in this case, “About”) and you’ll see the Name field automatically populate. You can give it a Description if you’d like. Finally, make sure the Annotation is set to “Single” since you’ll only need one page of this type.&lt;/p&gt;

&lt;p&gt;Now, you can add additional fields for your “About” page by dragging-and-dropping some widgets from the left sidebar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Block Canvas&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Biography.” This is an optional field where you can share a little more information about who you are.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asset&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Portrait.” This is an optional field, which you’ll use to save a flattering headshot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repeater&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Social Profiles.” The &lt;strong&gt;Repeater&lt;/strong&gt; widget is a little different from other widgets since you put other widgets inside of it. This will let you save several of your social profiles on your “About” page, all with identical fields. Drag-and-drop the following widgets into the &lt;strong&gt;Repeater’s&lt;/strong&gt; drop zone:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Line&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Profile URL” and check the “Required” box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single Line&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Social Network” and check the “Required” box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asset&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Social Network Icon.” This will be an optional field.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you’re all done, click the green &lt;strong&gt;Save Content Type&lt;/strong&gt; button. You’ll then be taken to your blank “About” page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edit The About Page
&lt;/h3&gt;

&lt;p&gt;Editing the content of the “About” page is the same as creating a “Project” page and filling in the fields. In Biography, tell the world your story with rich links, headings, images, and embeds.  Upload your handsome mug to the Portrait field. And link to all your social networks using Social Profiles repeater. Since repeaters are new in this walkthrough, we’ll spend a moment on its unique interface.&lt;/p&gt;

&lt;p&gt;New repeater entries can be created by clicking on the round plus &lt;strong&gt;[+]&lt;/strong&gt; button. Repeater entries can be edited just like any other field and assets like the Social Network Icon field present the same interface as anywhere else. A special feature of repeater elements is that they can be rearranged, expanded and collapsed. At the top of the repeater field, you can expand-all or collapse-all of the entries with a single click. Play around with the repeater and get a feel for it; it’s a big part of what makes modeling content in TakeShape so powerful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5TSy9qF5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/e5v5xd1dxnoj0jn4dk8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5TSy9qF5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/e5v5xd1dxnoj0jn4dk8x.png" alt="Filling in About Page Content Entry In TakeShape"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you’re done editing the “About” page, click the green &lt;strong&gt;Save&lt;/strong&gt; button. Since the “About” page is a single content type, you won’t be taken back to any kind of list after saving. You’ll stay right on the same content type since it’s the only one of its kind!&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Client Taxonomy Content Type
&lt;/h3&gt;

&lt;p&gt;Your design portfolio will include work for a few different clients so you’ll want be able to organize your projects by client. To do this, create a Client Taxonomy content type. Taxonomies are a special &lt;em&gt;Annotation&lt;/em&gt; in TakeShape that allows you to easily sort and filter collections.&lt;/p&gt;

&lt;p&gt;To create this new content type, follow the same steps as before. Start by clicking the green &lt;strong&gt;Add Content Type&lt;/strong&gt; button at the bottom of the left-hand sidebar. Give your new content type a &lt;em&gt;Title&lt;/em&gt; (“Client”), let the Name auto-populate, and then give it a &lt;em&gt;Description&lt;/em&gt; like “Clients commission the projects in my portfolio.” Then, change the &lt;em&gt;Annotation&lt;/em&gt; from “Multiple” to “Taxonomy.” Finally, add three widgets to the content type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Line Text&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Name” and check the “Required” box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single Line Text&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “URL” and check the “Required” box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asset&lt;/strong&gt;: In the &lt;em&gt;Title&lt;/em&gt; field enter “Logo.” This is an optional field.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, click the green &lt;strong&gt;Save Content Type&lt;/strong&gt; button. You’ll be taken to an empty list of clients.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Clients
&lt;/h3&gt;

&lt;p&gt;Editing a Taxonomy is the same as editing a Multiple content type. Click the &lt;strong&gt;Add Client&lt;/strong&gt; button from the top of the “Client” page. Fill in the available fields, adding your client’s &lt;em&gt;Name&lt;/em&gt;, &lt;em&gt;URL&lt;/em&gt;, and &lt;em&gt;Logo&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Then save your changes to be taken back to the list of clients. If you’d like to create a bunch of clients without being taken back to the list view each time, you can click &lt;strong&gt;Save and add another&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relate Clients to Projects
&lt;/h3&gt;

&lt;p&gt;There’s one last step to take: you’ll need to update the Project content type to allow clients to be added to projects. On the left sidebar, you should see the list of content types you created. Click the gear icon &lt;strong&gt;[⚙]&lt;/strong&gt; next to the “Project” entry to edit this content type. Drag in a &lt;strong&gt;Relationship&lt;/strong&gt; widget. Give it a Title (“Client”) and a Description, then set the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;em&gt;Relationship&lt;/em&gt; Type to “Single.” If you want to be able to add multiple clients to a project, choose “Multiple” instead.&lt;/li&gt;
&lt;li&gt;Set &lt;em&gt;Allowed Content Types&lt;/em&gt; to “Client.”&lt;/li&gt;
&lt;li&gt;Set &lt;em&gt;Reverse Name&lt;/em&gt; to “projects.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mWX-aypD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jrp8feqq3k3kc7hmkamv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mWX-aypD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jrp8feqq3k3kc7hmkamv.png" alt="Edit Project Content Type Client in TakeShape"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the green &lt;strong&gt;Update Content Type&lt;/strong&gt; button. &lt;/p&gt;

&lt;p&gt;When you’re ready to add a client to a project, you can search the clients you’ve already created or add a new one. When creating a new client you’ll only be able to edit its required fields, like &lt;em&gt;Name&lt;/em&gt; and &lt;em&gt;URL&lt;/em&gt;. You can update other client fields, like &lt;em&gt;Logo&lt;/em&gt;, after it’s been created.&lt;/p&gt;

&lt;p&gt;Finally, when your projects have been associated with clients, you can filter your list of projects by searching for the client’s name in the &lt;em&gt;Filter&lt;/em&gt; field at the top of the page. Thanks, Taxonomies! &lt;/p&gt;

&lt;p&gt;Now you can create projects and clients, associate them with each other, and organize your portfolio.&lt;/p&gt;

&lt;h3&gt;
  
  
  Surprise, You Also Built A GraphQL API!
&lt;/h3&gt;

&lt;p&gt;Now that you’ve modeled your content and created some entries, you can see the API that TakeShape has automatically generated for you. Open your “Project” page from the left sidebar and select any project from the list. Once you’re in the content editor, click the button labelled &lt;strong&gt;View in API Explorer&lt;/strong&gt; on the right side-bar to view the API query. Once the “API Explorer” window is open, click the &lt;strong&gt;Play&lt;/strong&gt; button to see the results for querying for this piece of content. You can also enter the “API Explorer” at any time by choosing it from the drop-down navigation menu at the top of the sidebar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jEqpmMV9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6sgyfvnm7zrvwmc9mbr1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jEqpmMV9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6sgyfvnm7zrvwmc9mbr1.png" alt="TakeShape View In API Explorer Button in Content Entry Sidebar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0NWv5yc9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/lv2s5ltashm2rhpidhvb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0NWv5yc9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/lv2s5ltashm2rhpidhvb.png" alt="TakeShape API Explorer Query and JSON Result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create A Static Site
&lt;/h3&gt;

&lt;p&gt;Now that you have a customized CMS for your portfolio project you can easily update your projects and clients. In part 2 you'll create a unique static website to display your projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested in Creative Tools to Build Custom Websites?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt; is a headless GraphQL CMS and static site generator. At TakeShape we're committed to building the best CMS tools possible for the most creative designers and developers. With our project templates, it's easy to get started. Plus, our pricing is flexible and affordable. &lt;a href="https://app.takeshape.io/signup"&gt;Sign up for a free account&lt;/a&gt; and spend more time being creative! &lt;/p&gt;

</description>
      <category>design</category>
      <category>tutorial</category>
      <category>learning</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why The Best Websites Are Static</title>
      <dc:creator>Mark Catalano</dc:creator>
      <pubDate>Fri, 05 Oct 2018 21:28:17 +0000</pubDate>
      <link>https://forem.com/takeshape/why-the-best-websites-are-static-3577</link>
      <guid>https://forem.com/takeshape/why-the-best-websites-are-static-3577</guid>
      <description>&lt;p&gt;All websites are different, but three things every website needs to be are safe, fast, and cost-effective. Static websites are all three. Publishers, who have lost patience with the ongoing maintenance, outsized cost, and unreliable performance of dynamically generated websites, are now  embracing the built-in benefits of going static. And as more tools and services rise to meet the needs of static websites, it’s quickly becoming the case that most—if not all—websites should be static from the start.&lt;/p&gt;

&lt;p&gt;So just how fast, secure, and affordable are static sites? By only serving static HTML files—with most weighing in at only a few dozen kilobytes—the cost of hosting a website falls to pennies per day. When those lightweight static files are distributed on a content-delivery network (CDN), loading times evaporate. A well-designed static website on a CDN can load in a just few dozen milliseconds.  Static sites, with their speedy load times, are more likely to be preferred by search engines and rise higher in the results. And when that blog post or landing page goes viral, there’s no chance that the site will go down. Best of all, static websites are secure by default because there’s no data collected, there’s no session tokens, and there’s no security holes for an attacker to breach. It’s a simple solution. It just works.&lt;/p&gt;

&lt;p&gt;The speed, security, and affordability of static sites is a consequence of their simplicity. So perhaps the biggest reason why we’ve seen an explosion in the number of static sites is that they’re just less complicated. Together, we’ve come to realize that most sites are just better if they’re left static. Static site generators like &lt;a href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt;, &lt;a href="https://gohugo.io/"&gt;Hugo&lt;/a&gt;, and &lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby&lt;/a&gt; have made it simple to quickly create all the pages a static site needs by reducing them to a handful of design templates and content folders. Why pay to keep a rendering server running nonstop just to deliver a simple blog post that probably won’t ever change after it’s published? Why build up an entire database infrastructure behind a single product landing page?&lt;/p&gt;

&lt;p&gt;As the popularity of static sites has grown, new tools and solutions have arisen to eliminate some of the downsides to choosing to go static, like providing a user-friendly CMS (&lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt;), handling user-generated content (Formstack), and integrating with third-party APIs (edge functions). Even better, these new tools are informed by the same values of speed, security, and simplicity. An entire new software architecture, &lt;a href="https://jamstack.org/"&gt;JAMstack&lt;/a&gt; (Javascript, APIs, and Markup), has rapidly grown out of this static-first approach. By building beautiful web applications on the foundations of a static site, all the tools up the stack get to be simpler, faster, and more secure, as well. It’s now possible to have the best of both worlds: a simple static website and a richly-interactive web application, at the same time.&lt;/p&gt;

&lt;p&gt;One problem to going static used to be content management: none of the existing solutions like Wordpress or Drupal work with this static-first approach. As a consequence, there’s been incredible progress reimagining what a CMS should be for this new static era. Rather than have an old, monolithic CMS managing the content, rendering the content, and serving the content, the next-generation of CMS treat their content as a service. These new headless CMS, so-called because they don’t attempt to render a dynamic website at all, instead just publish their data for static site generators to grab and use when they’re building a site. For example, &lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt; allows its users to create and edit content like posts, pages, or products—and creates a GraphQL API for it. On its own, this API could provide the content for any static site; but to make things faster and easier for developers, &lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt; has created their own static site generator that talks to the API for you. Like the static sites they feed their data to, a content-as-a-service CMS ends up being faster, safer, and cheaper than a legacy system like Wordpress, while keeping the rich web editing interface we’ve grown familiar with.&lt;/p&gt;

&lt;p&gt;Another problem static sites have faced is receiving and handling input from users, from simple contact forms to complex checkout systems. The &lt;a href="https://www.martinfowler.com/articles/serverless.html"&gt;serverless movement&lt;/a&gt; has grown to solve this problem elegantly. With a more complete service like &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt; or &lt;a href="https://serverless.com/"&gt;just a one-off AWS Lambda function&lt;/a&gt;, input handling and server-side code is now easier to develop, cheaper to run, and more secure than ever before. It’s not surprising that the serverless and static trends have grown alongside one another—they’re a perfect match. Together, they vastly simplify the existing complexity of creating a website.&lt;/p&gt;

&lt;p&gt;Finally, we no longer have to choose between a static site and web applications. We can have our cake and eat it, too! &lt;a href="https://alistapart.com/article/understandingprogressiveenhancement"&gt;Progressive enhancement&lt;/a&gt;, a design best-practice of providing a consistent baseline experience and then building upon it with more sophisticated functionality, has totally changed how we think about delivering interactivity on the web. With the increasing sophistication of client-side Javascript frameworks like &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt;, &lt;a href="https://vuejs.org/"&gt;Vue&lt;/a&gt;, and &lt;a href="https://angularjs.org/"&gt;Angular&lt;/a&gt;, it’s now possible to deliver a simple static site that progressively unfolds into a highly functional web application. Everybody can have a reliable and delightful experience, from the most data-constrained mobile devices to the fastest desktops with a hardwired Gigabit network connection. More importantly, it means that now there’s even fewer reasons for websites not to start from a lightweight, speedy static foundation.&lt;/p&gt;

&lt;p&gt;It’s clear that bloated, unwieldy, and insecure dynamic websites are quickly becoming obsolete. Leaving those tools in the past, we should work to build a web where speed, security, and affordability are easy to achieve. It’s simpler than ever, with tools like TakeShape to publish a static site, keep it updated, and even give it the rich interactivity we’ve come to expect on the web. The future of the web is static, and it’s going to stay that way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested in CMS for Static Sites?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt; is a headless GraphQL CMS and static site generator. At &lt;a href="https://www.takeshape.io/"&gt;TakeShape&lt;/a&gt; we're committed to building the best CMS tools possible for developers and content creators. It's easy to get started and we offer flexible pricing. &lt;a href="https://app.takeshape.io/signup"&gt;Sign up for an account today&lt;/a&gt;. Developer projects are always free!&lt;/p&gt;

</description>
      <category>static</category>
      <category>webdev</category>
      <category>discuss</category>
      <category>devtips</category>
    </item>
  </channel>
</rss>
