<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: weibenfalk</title>
    <description>The latest articles on DEV Community by weibenfalk (@weibenfalk).</description>
    <link>https://dev.to/weibenfalk</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%2F98130%2F5cc31623-a7b6-4d2f-9f63-e292ca87dad1.png</url>
      <title>DEV Community: weibenfalk</title>
      <link>https://dev.to/weibenfalk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/weibenfalk"/>
    <language>en</language>
    <item>
      <title>NextJS 13 - Refactor a complete App to NextJS 13</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Mon, 31 Oct 2022 07:15:36 +0000</pubDate>
      <link>https://dev.to/weibenfalk/nextjs-13-refactor-a-complete-app-to-nextjs-13-4p7e</link>
      <guid>https://dev.to/weibenfalk/nextjs-13-refactor-a-complete-app-to-nextjs-13-4p7e</guid>
      <description>&lt;p&gt;I'll show how to refactor a complete NextJS 12 Application into NextJS version 13. I'll use the new App folder, server components and client components. On the client I'll also show how to setup React-Query (Tanstack Query) to work in NextJS v13. I'll also use Typescript.&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Advanced React Context with Typescript</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Tue, 18 Oct 2022 11:28:48 +0000</pubDate>
      <link>https://dev.to/weibenfalk/advanced-react-context-with-typescript-2c6o</link>
      <guid>https://dev.to/weibenfalk/advanced-react-context-with-typescript-2c6o</guid>
      <description>&lt;p&gt;Time to talk about context again! This time it's more advanced and I'll talk about using React Context with Typescript. I'll also show how to create a custom hook and a component to use the context. Finally I'll show how to memoize the context.&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>React Quiz tutorial | with Typescript</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Tue, 07 Jul 2020 13:27:41 +0000</pubDate>
      <link>https://dev.to/weibenfalk/react-quiz-tutorial-with-typescript-15pk</link>
      <guid>https://dev.to/weibenfalk/react-quiz-tutorial-with-typescript-15pk</guid>
      <description>&lt;p&gt;In this tutorial, I'll show you how to build a Quiz game in React with an open API for the questions. I'll use Typescript and Styled Components with React.&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CSS Grid Tutorial | Frontend Mentor Challenge</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Tue, 30 Jun 2020 13:47:15 +0000</pubDate>
      <link>https://dev.to/weibenfalk/css-grid-tutorial-frontend-mentor-challenge-m4</link>
      <guid>https://dev.to/weibenfalk/css-grid-tutorial-frontend-mentor-challenge-m4</guid>
      <description>&lt;p&gt;Frontendmentor is a cool place where you can find challenges of different levels. In this free video tutorial, I'll show how I tackled one of the challenges. 😃&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Svelte Routing | page.js as routing for Svelte JS</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Wed, 24 Jun 2020 13:05:06 +0000</pubDate>
      <link>https://dev.to/weibenfalk/svelte-routing-page-js-as-routing-for-svelte-js-58pf</link>
      <guid>https://dev.to/weibenfalk/svelte-routing-page-js-as-routing-for-svelte-js-58pf</guid>
      <description>&lt;p&gt;Svelte is cool ... So cool that I created a premium beginner course on it. =) This video is from that course. I'll show you how to create routes easily in Svelte with a tiny library called page.js&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>development</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Free tutorials on React, Gatsby, Svelte, HTML, CSS and Javascript</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Sat, 13 Jun 2020 15:24:42 +0000</pubDate>
      <link>https://dev.to/weibenfalk/free-tutorials-on-react-gatsby-svelte-html-css-and-javascript-2k82</link>
      <guid>https://dev.to/weibenfalk/free-tutorials-on-react-gatsby-svelte-html-css-and-javascript-2k82</guid>
      <description>&lt;p&gt;Hey.&lt;/p&gt;

&lt;p&gt;I'm Thomas from Sweden. 🇸🇪&lt;/p&gt;

&lt;p&gt;I'm a developer and Course/Tutorial creator on modern Front End stuff.I have created a lot of premium courses but decided I want to publish free tutorials on my own Youtube channel. I put out weekly free videos and my goal is to keep it fun, down to earth, and easy to understand. People really seem to like my teaching style so the channel is starting to do great.&lt;/p&gt;

&lt;p&gt;I love React so there's a lot of React stuff. But also Vanilla JS, CSS, HTML, Gatsby, and Svelte. I also do some occasional backend stuff.&lt;/p&gt;

&lt;p&gt;So ... just wanted to drop a friendly post to come join my channel if you want to learn modern development for free. 😃&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/user/Weibenfalk"&gt;https://www.youtube.com/user/Weibenfalk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FPs_q8jE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mka0vn9qk902u3uc9k3f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FPs_q8jE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mka0vn9qk902u3uc9k3f.jpg" alt="Weiben"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to check out my premium courses also you can go to &lt;a href="http://www.weibenfalk.com"&gt;www.weibenfalk.com&lt;/a&gt; ... I've actually discounted them with 90 percent now in the Corona times.&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>developer</category>
      <category>coding</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Custom React Hook - useLocalStorage</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Tue, 12 May 2020 14:12:59 +0000</pubDate>
      <link>https://dev.to/weibenfalk/custom-react-hook-uselocalstorage-n9i</link>
      <guid>https://dev.to/weibenfalk/custom-react-hook-uselocalstorage-n9i</guid>
      <description>&lt;p&gt;This week I show how to create a custom React Hook for automating Local Storage. And ... it's written in Typescript ;)&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>development</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Developers Diary Ep 1 - Week #19</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Tue, 12 May 2020 14:12:13 +0000</pubDate>
      <link>https://dev.to/weibenfalk/developers-diary-ep-1-week-19-2ldd</link>
      <guid>https://dev.to/weibenfalk/developers-diary-ep-1-week-19-2ldd</guid>
      <description>&lt;p&gt;I'm starting a new talk on my Youtube channel. Thought it could be of value to hear what "real life" code problems I experience in client work. That's why I do this talk.&lt;/p&gt;

&lt;p&gt;It's one thing to learn from tutorials and articles but these are often fictive cases. So ... I want to do a down to earth talk about how the real working life as a developer is. From time to time on my Youtube channel.&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>development</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Vanilla JS Spaceship with gravity</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Tue, 05 May 2020 14:10:04 +0000</pubDate>
      <link>https://dev.to/weibenfalk/vanilla-js-spaceship-with-gravity-1dcb</link>
      <guid>https://dev.to/weibenfalk/vanilla-js-spaceship-with-gravity-1dcb</guid>
      <description>&lt;p&gt;In this video you'll learn how to build a vector spaceship with canvas. The spaceship is controlled with the keyboard and affected by gravity.&lt;/p&gt;

&lt;p&gt;This is inspired by the old Amiga game Gravity Force&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Life as a freelancer</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Thu, 30 Apr 2020 14:23:58 +0000</pubDate>
      <link>https://dev.to/weibenfalk/life-as-a-freelancer-45af</link>
      <guid>https://dev.to/weibenfalk/life-as-a-freelancer-45af</guid>
      <description>&lt;p&gt;Gonna start doing small talks on my YT channel also. Talk about life as a developer and other stuff related to coding. &lt;/p&gt;

&lt;p&gt;This is todays talk. &lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>freelance</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>React Router 6 and more ...</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Wed, 29 Apr 2020 08:34:45 +0000</pubDate>
      <link>https://dev.to/weibenfalk/react-router-6-and-more-5e42</link>
      <guid>https://dev.to/weibenfalk/react-router-6-and-more-5e42</guid>
      <description>&lt;p&gt;Hi ... it's been a while since I was active here. I've had a lot to do. Just released my Beginner Gatsby course and also produce videos each week on my Youtube channel. My idea is to start posting my Youtube videos here to remind you of my free content in that channel. =) &lt;/p&gt;

&lt;p&gt;You can check out my channel here: &lt;a href="https://www.youtube.com/user/Weibenfalk"&gt;https://www.youtube.com/user/Weibenfalk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I post mostly stuff in #react and #frontend .. But sometimes I do backend stuff and try out new libraries and more. &lt;/p&gt;

&lt;p&gt;For example ... this week I try out the alpha build of React Router v6:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/J4faOAn6NGA"&gt;https://youtu.be/J4faOAn6NGA&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;If you're interested in my premium courses check out my course page: &lt;br&gt;
&lt;a href="https://www.weibenfalk.com"&gt;https://www.weibenfalk.com&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;There's my new Gatsby course and it's discounted 50%. I also have my pretty popular React Movie course there where you can learn the fundamentals and intermediate React.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>3 ways to edit Markdown with TinaCMS + Gatsby</title>
      <dc:creator>weibenfalk</dc:creator>
      <pubDate>Thu, 09 Jan 2020 18:43:47 +0000</pubDate>
      <link>https://dev.to/weibenfalk/3-ways-to-edit-markdown-with-tinacms-gatsby-3i48</link>
      <guid>https://dev.to/weibenfalk/3-ways-to-edit-markdown-with-tinacms-gatsby-3i48</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://tinacms.org/blog/three-ways-to-edit-md/"&gt;TinaCMS.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Supercharge your static site with real-time content editing!&lt;/strong&gt; 🚀&lt;/p&gt;

&lt;p&gt;In this post, I will explore &lt;em&gt;the three different methods&lt;/em&gt; Tina offers to edit Markdown on your Gatsby site. You’ll learn how to set up Tina with both Page Queries and Static Queries.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post will not cover the basics of using Tina with Gatsby. Please reference the &lt;a href="https://tinacms.org/docs/gatsby/manual-setup"&gt;documentation&lt;/a&gt; on how to initially set up Tina with Gatsby.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s the deal with Page Queries and Static Queries?
&lt;/h2&gt;

&lt;p&gt;Before we dive down into editing Markdown with Tina we have to understand how Gatsby handles querying data with GraphQL. You can source data from almost anywhere in Gatsby. In our case, we’re using &lt;em&gt;Markdown&lt;/em&gt;. When you build your site, Gatsby creates a GraphQL schema for all the data. Then you use &lt;a href="https://graphql.org/learn/"&gt;GraphQL&lt;/a&gt; in your React components to query your sourced data.&lt;/p&gt;

&lt;p&gt;Gatsby allows you to query your data in two ways: &lt;a href="https://www.gatsbyjs.org/docs/static-vs-normal-queries/"&gt;&lt;em&gt;Page Queries and Static Queries&lt;/em&gt;&lt;/a&gt;.&lt;br&gt;
Since the release of the &lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;React Hooks API&lt;/a&gt; and the &lt;a href="https://www.gatsbyjs.org/docs/use-static-query/"&gt;&lt;code&gt;useStaticQuery&lt;/code&gt; hook&lt;/a&gt; in Gatsby, it is very easy to query your data. There are cases when you can’t use a Static Query though. First, let’s explore the differences.&lt;/p&gt;
&lt;h3&gt;
  
  
  The two main differences are:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Page Queries can accept GraphQL variables. Static Queries can’t.&lt;/li&gt;
&lt;li&gt;Page Queries can only be added to page components. Static Queries can be used in all components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, why can’t we use GraphQL variables in a Static Query? The reason for that is a Static Query doesn’t have access to the page context like a Page Query does. The result is that a Static Query won’t be able to access variables that are defined in the page context. You can define the page context in your &lt;code&gt;gatsby-node.js&lt;/code&gt; file in your &lt;code&gt;createPage&lt;/code&gt; function. Here you can supply your page with different variables that will get injected to your page on build time.&lt;/p&gt;

&lt;p&gt;I use Static Queries as much as possible because I love the hooks API and the ease of composition possibilities it brings. For example, you can create custom hooks and reuse them in multiple components.&lt;/p&gt;

&lt;p&gt;Let’s say that you have a GraphQL query that grabs metadata that you want on multiple pages. Create a custom React hook with the &lt;code&gt;useStaticQuery&lt;/code&gt; Gatsby hook inside of it. Then you can use your custom hook wherever you want and always easily get that data into your component. When you need to have variables in your component, you have to use a Page Query. Page Queries cannot be used with the hooks API and have to be unique and attached to the specific page component.&lt;/p&gt;

&lt;p&gt;Another great thing with Static Queries is that you can grab the data in the component that needs the data. That prevents &lt;a href="https://kentcdodds.com/blog/prop-drilling"&gt;&lt;em&gt;prop drilling&lt;/em&gt;&lt;/a&gt; and your data is more tightly coupled to the component where it is used.&lt;/p&gt;
&lt;h2&gt;
  
  
  React overview
&lt;/h2&gt;

&lt;p&gt;For getting data, we can use Gatsby's query options. For structuring our components, React also offers a couple of options. You can either create your component as a &lt;a href="https://reactjs.org/docs/components-and-props.html"&gt;class or a functional component&lt;/a&gt;. Before the React Hooks API, you had to use class components to have state in your components. Now with hooks, you can do this with functional components.🥰&lt;/p&gt;
&lt;h2&gt;
  
  
  Three ways to edit markdown with Tina
&lt;/h2&gt;

&lt;p&gt;Given all the options for creating components and souring data in Gatsby, we have to choose the most suitable approach for the project. Tina can work with all of these options, providing &lt;strong&gt;three different approaches&lt;/strong&gt; for editing Markdown with Gatsby as described below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;remarkForm&lt;/strong&gt; - A &lt;a href="https://reactjs.org/docs/higher-order-components.html"&gt;Higher Order Component&lt;/a&gt; used when you source data from a Page Query in Gatsby. This component can be utilized with both functional and class components. Please note the subtle difference here! The only difference in naming from the render props component is the lowercase “r”.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;useLocalRemarkForm&lt;/strong&gt; - A &lt;a href="https://reactjs.org/docs/hooks-overview.html"&gt;React Hook&lt;/a&gt; that is intended for functional components sourcing data from either a Static or a Page Query. If the component is sourcing static data, Gatsby's &lt;code&gt;useStaticQuery&lt;/code&gt; hook would be called.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RemarkForm&lt;/strong&gt; - A &lt;a href="https://reactjs.org/docs/render-props.html"&gt;Render Props Component&lt;/a&gt; that you can use in class components sourcing data from either a Static or a Page Query. Static data would be sourced via Gatsby’s &lt;code&gt;StaticQuery&lt;/code&gt; render props component.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  remarkForm - How to use it and why it won’t work with Static Queries.
&lt;/h3&gt;

&lt;p&gt;First, Let’s dive into how to hook up TinaCMS with a Page Query.&lt;br&gt;
The &lt;code&gt;remarkForm&lt;/code&gt; Component in TinaCMS is a &lt;a href="https://reactjs.org/docs/higher-order-components.html"&gt;Higher Order Component&lt;/a&gt;, a HOC in short. This means that it is a function that takes in another component and will return a new component that has added functionality to it.&lt;/p&gt;

&lt;p&gt;If you’re not familiar with HOC's, I suggest you read about them in the &lt;a href="https://reactjs.org/docs/higher-order-components.html"&gt;&lt;b&gt;React official docs&lt;/b&gt;&lt;/a&gt;. They are considered “advanced usage” in the React world.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;remarkForm&lt;/code&gt; component wants another component as an argument and is intended for Page Queries. A Page Query injects the data as a prop to the component and we access the data from this prop. With a &lt;code&gt;useStaticQuery&lt;/code&gt; hook, the data is collected in a variable, that you choose, inside the component itself. That means if you're using the &lt;code&gt;useStaticQuery&lt;/code&gt; hook in Gatsby you won’t have a component to give the &lt;code&gt;remarkForm&lt;/code&gt; HOC. Bummer!😞 That’s why you can only use the &lt;code&gt;remarkForm&lt;/code&gt; component with Page Queries.&lt;/p&gt;

&lt;p&gt;So &lt;strong&gt;how do you use this component with a Page Query&lt;/strong&gt; in Gatsby? First, check out the fictive Star Wars component below. It will show the three steps needed to hook everything up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Import the `remarkForm` HOC&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;remarkForm&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="s1"&gt;gatsby-tinacms-remark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StarWarsMovie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;markdownRemark&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="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;markdownRemark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&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="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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Wrap your component with `remarkForm`&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;remarkForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;StarWarsMovie&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// 3. Add the required ...TinaRemark fragment to your Page Query&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;pageQuery&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 StarWarsMovieById($id: String!) {
    markdownRemark(fields: { id: { eq: $id } }) {
      id
      html
      frontmatter {
        title
        releaseDate
        crawl
      }
      ...TinaRemark
    }
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above code is a component that displays information about Star Wars movies. For now, it just displays a title, but it could also display the release date and the crawl text in the intro to the film. But that’s another story in a galaxy far far away ... ⭐&lt;/p&gt;

&lt;p&gt;The first step in this example is to import the &lt;code&gt;remarkForm&lt;/code&gt; hook from the Gatsby plugin ‘gatsby-tinacms-remark’. This is the plugin that &lt;em&gt;makes TinaCMS work with Markdown files&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There’s no need to do any additions to the code inside of the component itself. It could be any component — functional or class — structured in the way you want it. The only thing you have to do with the component itself is to wrap your component with the &lt;code&gt;remarkForm&lt;/code&gt; HOC when you export it.&lt;/p&gt;

&lt;p&gt;One more thing you have to do before you are good to go is to add the GraphQL fragment &lt;code&gt;...TinaRemark&lt;/code&gt; in your query. This is needed for TinaCMS to recognize your data and create the required editor fields in the TinaCMS sidebar. After that, you only have to start up your dev server to show the site and the Tina sidebar.&lt;/p&gt;

&lt;p&gt;Easy enough isn’t it? Just three small steps and you’ll have a beautiful sidebar to edit your content on your site. 🤟&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But what if you want to use a Static Query and not a Page Query?&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  useLocalRemarkForm to the rescue!
&lt;/h3&gt;

&lt;p&gt;We’ve learned that the &lt;code&gt;remarkForm&lt;/code&gt; HOC won’t work on Static Queries. So we’ll have to find another solution for using Static Queries with TinaCMS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Great news!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;remarkForm&lt;/code&gt; component is essentially a "wrapper" for the &lt;code&gt;useLocalRemarkForm&lt;/code&gt; hook. 👀 It takes in a component as an argument, calls &lt;code&gt;useLocalRemarkForm&lt;/code&gt; with the Page Query data and returns a new component with the query data and TinaCMS connected to it.&lt;/p&gt;

&lt;p&gt;We can use the &lt;code&gt;useLocalRemarkForm&lt;/code&gt; hook directly, without using the &lt;code&gt;remarkForm&lt;/code&gt; HOC. This can be useful with Static Queries or if we just prefer working with hooks!&lt;/p&gt;

&lt;p&gt;Take a look at the code example below to get an idea of how &lt;code&gt;useLocalRemarkForm&lt;/code&gt; works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Import useLocalRemarkForm hook&lt;/span&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="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="err"&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;useLocalRemarkForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;gatsby&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;tinacms&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;remark&lt;/span&gt;&lt;span class="err"&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;useStaticQuery&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;gatsby&lt;/span&gt;&lt;span class="err"&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;StarWarsMovie&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="c1"&gt;// 2. Add required TinaCMS fragment to the GrahpQL query&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStaticQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
      query StarWarsMovieById {
        markdownRemark(fields: { id: { eq: "sw-01" } }) {
          id
          html
          frontmatter {
            title
            releaseDate
            crawl
          }
          ...TinaRemark
        }
      }
    `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// 3. Call the useLocalRemarkForm hook and pass in the data&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;markdownRemark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocalRemarkForm&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;markdownRemark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&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;markdownRemark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&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="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="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;StarWarsMovie&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is just an example component illustrating how &lt;code&gt;useLocalRemarkForm&lt;/code&gt; works. In the real world, it would not be an optimal solution using a Static Query for this. That’s because, as you can see, you can’t use variables inside the &lt;code&gt;useStaticQuery&lt;/code&gt; hook to make it dynamic. You have to hardcode the movie id. So this query will work for that specific movie only, which is no good.&lt;/p&gt;

&lt;p&gt;Let’s break down what’s happening here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We import the &lt;code&gt;useLocalRemarkForm&lt;/code&gt; custom hook so we can use it in our component.&lt;/li&gt;
&lt;li&gt;Just as before, the &lt;code&gt;...TinaRemark&lt;/code&gt; fragment is needed in the GraphQL query. So we add that one there.&lt;/li&gt;
&lt;li&gt;When we’ve got our data back from the Gatsby &lt;code&gt;useStaticQuery&lt;/code&gt; hook we can call the TinaCMS &lt;code&gt;useLocalRemarkForm&lt;/code&gt; hook with that data. This hook will return an array with two elements. The first element is practically the data that we called the hook with. It has the same shape and is ready for us to use in our component. The second element is a reference to the Tina form. We don’t need that one so we don’t destructure it out as we do with the &lt;code&gt;markdownRemark&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're wondering about this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;markdownRemark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocalRemarkForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;heroData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;markdownRemark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It is an example of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment"&gt;ES6 destructuring&lt;/a&gt;. As we get an array with two elements back, I destructure out the first element (which is our data) and name it &lt;code&gt;markdownRemark&lt;/code&gt;. You can name it whatever you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  RemarkForm - The Render Prop Component
&lt;/h3&gt;

&lt;p&gt;You can’t use React Hooks on class components. That’s why Tina provides a &lt;a href="https://tinacms.org/docs/gatsby/markdown/#2-the-render-props-component-remarkform"&gt;&lt;code&gt;RemarkForm&lt;/code&gt;&lt;/a&gt; component that uses the &lt;a href="https://reactjs.org/docs/render-props.html"&gt;Render Props&lt;/a&gt; pattern.&lt;/p&gt;

&lt;p&gt;This component works with both Page and Static Queries. I will show how to use it with a Page Query below.&lt;/p&gt;

&lt;p&gt;Take a look at below example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. import the RemarkForm render prop component&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;RemarkForm&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="s1"&gt;@tinacms/gatsby-tinacms-remark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;StarWarsMovie&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/*
     ** 2. Return RemarkForm, pass in markdownRemark
     **    to the remark prop and pass in what you
     **    want to render to the render prop
     */&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;RemarkForm&lt;/span&gt;
        &lt;span class="nx"&gt;remark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;markdownRemark&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;markdownRemark&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="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;markdownRemark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&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="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="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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;StarWarsMovie&lt;/span&gt;

&lt;span class="c1"&gt;// 3. Add the required ...TinaRemark fragment to your Page Query&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;pageQuery&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 StarWarsMovieById($id: String!) {
    markdownRemark(fields: { id: { eq: $id } }) {
      id
      html
      frontmatter {
        title
        releaseDate
        crawl
      }
      ...TinaRemark
    }
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ok, yet again, let’s see what’s happening here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We import the &lt;code&gt;RemarkForm&lt;/code&gt; component for us to use in our code.&lt;/li&gt;
&lt;li&gt;In our return statement we return the &lt;code&gt;RemarkForm&lt;/code&gt; component and pass in it's predefined, and required props. The remark prop provides &lt;code&gt;RemarkForm&lt;/code&gt; with the markdown data sourced from the Page Query. The render prop gets the JSX that we want to render through a function, or a render prop. &lt;code&gt;RemarkForm&lt;/code&gt; will hook up Tina for editing the data and then render whatever is specified in the render prop function.&lt;/li&gt;
&lt;li&gt;Just as before we have to add the &lt;code&gt;...TinaRemark&lt;/code&gt; fragment to the Page Query.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;strong&gt;That's it&lt;/strong&gt;! Three ways of using Tina for editing Markdown files in Gatsby. 🎉&lt;/p&gt;

&lt;p&gt;In this post, we learned about how to &lt;em&gt;set up Tina with both Static Queries and Page Queries in Gatsby&lt;/em&gt;. We also learned about three different ways to edit markdown with Tina depending on your type of React component.&lt;/p&gt;

&lt;p&gt;This is just the basics to get you started. If you like Tina and want to learn more you should check out the &lt;a href="https://tinacms.org/docs/"&gt;official docs&lt;/a&gt;. There’s a lot more stuff to read there and some interesting use cases.&lt;/p&gt;

&lt;p&gt;For example, you can learn how to apply &lt;a href="https://tinacms.org/docs/gatsby/inline-editing"&gt;inline editing&lt;/a&gt; and also how to &lt;a href="https://tinacms.org/docs/gatsby/markdown#customizing-remark-forms"&gt;customize the form fields&lt;/a&gt; in the Tina sidebar.&lt;/p&gt;

&lt;p&gt;Tina is a great addition to the React ecosystem and static site generators like Gatsby. It gives your site a pleasant and easy way to edit and interact with your content.&lt;br&gt;
I’m thrilled to see how big TinaCMS will be and what it can do as it evolves!&lt;/p&gt;

&lt;h2&gt;
  
  
  More reading and learning
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://tinacms.org/docs/"&gt;Tina Official Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.tinacms.org/"&gt;Tina Community&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tina on Twitter: &lt;a href="https://twitter.com/tina_cms"&gt;@tina_cms&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Watch my tutorial for &lt;a href="https://www.youtube.com/watch?v=eZWJ9ZtF61A&amp;amp;t=265s"&gt;Tina &amp;amp; Gatsby&lt;/a&gt;. Also catch me on Twitter — &lt;a href="https://twitter.com/weibenfalk"&gt;@weibenfalk&lt;/a&gt;, &lt;a href="https://www.youtube.com/c/weibenfalk"&gt;Youtube&lt;/a&gt;, or on my &lt;a href="https://www.weibenfalk.com"&gt;website&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>gatsby</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
