<?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: Dominik Biedebach</title>
    <description>The latest articles on Forem by Dominik Biedebach (@bdbchgg).</description>
    <link>https://forem.com/bdbchgg</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%2F127310%2F16121f71-f56c-40b9-98f9-8826114382fe.jpg</url>
      <title>Forem: Dominik Biedebach</title>
      <link>https://forem.com/bdbchgg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bdbchgg"/>
    <language>en</language>
    <item>
      <title>Why Discord Sucks for Developer Communities</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Tue, 27 Jan 2026 18:40:24 +0000</pubDate>
      <link>https://forem.com/bdbchgg/why-discord-sucks-for-developer-communities-2fg1</link>
      <guid>https://forem.com/bdbchgg/why-discord-sucks-for-developer-communities-2fg1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This post is not meant to talk bad about Discord. It's a great messenger app for casual groups and communities. This is a post with a POV of an open source library maintainer trying to figure out the right way to use it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re maintaining an open-source library or building a community around a project, you’re eventually going to look for a place for that community to live. I’ve spent the last few years navigating this as a core maintainer of &lt;a href="https://tiptap.dev/" rel="noopener noreferrer"&gt;Tiptap&lt;/a&gt;—an open-source framework for building rich text editors.&lt;/p&gt;

&lt;p&gt;Four years ago, we thought Discord was the answer for the &lt;a href="https://github.com/ueberdosis/tiptap" rel="noopener noreferrer"&gt;Tiptap community&lt;/a&gt;. Fast forward to today, and I’d honestly tell any maintainer to stay away.&lt;/p&gt;




&lt;h2&gt;
  
  
  Discord is Great for Chat, Terrible for Everything Else
&lt;/h2&gt;

&lt;p&gt;Discord claims to be the best place for online communities. That’s probably true if you just want a closed-off corner of the web where people can &lt;strong&gt;chat about your project&lt;/strong&gt; in real-time. If that’s all you need, you’ll be fine.&lt;/p&gt;

&lt;p&gt;But if you have a real-world use case—like &lt;strong&gt;collecting feature requests, providing support, or building a searchable knowledge base&lt;/strong&gt;—Discord is a significant hurdle.&lt;/p&gt;

&lt;p&gt;Don’t get me wrong: as an app for real-time messaging, voice rooms, and screensharing, Discord is excellent. It’s still the best at those specific things. But for us at Tiptap, the wheels fall off the second you try to use it as a "one-size-fits-all" Chat+Forum hybrid.&lt;/p&gt;

&lt;p&gt;A linear chat is an inefficient place to hold specific technical discussions. Bug reports, feature requests, and random questions all bleed into each other. You end up with a single stream of messages where five different people are talking about five different things at once. It’s exhausting for both users and maintainers.&lt;/p&gt;

&lt;p&gt;Discord tried to fix this with Threads and Forum Channels. On paper, it sounds like a solution. In reality, the implementation lacks the depth required for professional OSS management.&lt;/p&gt;




&lt;h2&gt;
  
  
  Threads and Forum Channels Just Aren't Good Enough
&lt;/h2&gt;

&lt;p&gt;At Tiptap, we hit this exact wall. People were constantly talking over each other in one big mess. To fight the chaos, our team started asking people to use &lt;strong&gt;Threads&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Threads work if your server is tiny and you can manually police every message. But once you grow to the scale of a popular library, enforcing that rule is impossible. Discord doesn’t give maintainers the permissions to handle this properly—you can’t, for example, force a "threads-only" mode in a standard text channel. People just keep using the chat for what it is: a chat.&lt;/p&gt;

&lt;p&gt;I spent way too much time wondering how to fix this, and eventually, we pulled the trigger on &lt;strong&gt;Forum Channels&lt;/strong&gt;. These are basically mini-message boards that &lt;em&gt;force&lt;/em&gt; people to create a thread. At first, I was happy—the noise went down and the structure improved. But then I realized: &lt;strong&gt;user interaction completely cratered.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By trying to fix the noise, we accidentally stifled the &lt;strong&gt;community&lt;/strong&gt;. The casual small talk vanished. People only show up to our Discord now when they have a specific problem. Because the "vibe" is gone, other developers don't hang out there anymore, which means there’s no one left to help answer the questions.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Moderation is a Nightmare
&lt;/h3&gt;

&lt;p&gt;To make matters worse, managing Forum channels is unnecessarily difficult. For example, we have channels for community job postings and hiring profiles. People ignore the rules and post in the wrong spot constantly.&lt;/p&gt;

&lt;p&gt;In a real forum, I’d just move the post to the right category, edit the tags, or merge it with a duplicate. On Discord? You can’t move anything. You can’t merge threads. If someone spends 20 minutes writing a great post in the wrong channel, our only options are to delete their hard work or let the channel stay polluted. It’s counter-productive.&lt;/p&gt;

&lt;p&gt;We ended up with the worst of both worlds: a "community" that doesn't talk, and a forum that is hard to manage, impossible to search, and a pain to moderate.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Death of a Community
&lt;/h2&gt;

&lt;p&gt;Now that the Discord is effectively "dead" as a social hub, it’s just a closed-off support board. It’s not a place people visit to hang out or learn; it’s just a place to drop a question and leave. For any user who &lt;em&gt;doesn't&lt;/em&gt; have a problem right now, there is zero reason to be there.&lt;/p&gt;

&lt;p&gt;Because of that, we are planning to reopen the chat channels and move our actual "knowledge base" and forums away from Discord entirely.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Walled Garden Problem
&lt;/h2&gt;

&lt;p&gt;This is the biggest issue of all. On an open forum, anyone can use a search engine to find a solution to a problem. Discord, however, is a walled garden. Everything is locked behind a login.&lt;/p&gt;

&lt;p&gt;Search engines can’t index the thousands of helpful answers and discussions happening in your community. That means every time a user has a question, they can't find the answer on the web—they have to join your server and ask it all over again. It’s a massive waste of everyone's time.&lt;/p&gt;

&lt;p&gt;In 2026, this is even more critical. It’s not just about Google SEO anymore; &lt;strong&gt;it’s about LLM traffic.&lt;/strong&gt; AI crawlers and agents can’t learn from your community’s collective wisdom if it’s trapped inside a Discord channel. You are effectively hiding your documentation from the tools that developers use every day to find answers. You lose out on public traffic, you hurt your project's discoverability, and you force your maintainers to repeat themselves for eternity.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are the Alternatives?
&lt;/h2&gt;

&lt;p&gt;This is where the Tiptap team is currently stuck. We want to keep the Discord server for its original purpose (quick, real-time chatting), but we need a more structured, public solution for support and feature requests.&lt;/p&gt;

&lt;p&gt;We are looking at two main options:&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: GitHub Discussions
&lt;/h3&gt;

&lt;p&gt;Since &lt;a href="https://github.com/ueberdosis/tiptap" rel="noopener noreferrer"&gt;Tiptap&lt;/a&gt; already lives on GitHub, this is the "low friction" choice. Right now, it's underutilized because attention is usually split between Discord and GitHub Issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Pros:&lt;/strong&gt; It’s where the code lives. It integrates perfectly with Issues and Releases—you can turn a discussion into an issue with one click.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cons:&lt;/strong&gt; We don’t own it. If GitHub goes down or changes their terms, we’re at their mercy. Also, the SEO and crawler traffic stays on GitHub rather than our own project site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: Self-hosted Discourse
&lt;/h3&gt;

&lt;p&gt;This is the "pro" route. A self-hosted &lt;a href="https://www.discourse.org/" rel="noopener noreferrer"&gt;Discourse&lt;/a&gt; instance gives us 100% control over the theme, extensions, and moderation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Pros:&lt;/strong&gt; All that search and AI-agent traffic lands on our own domain. It makes the community feel like a "home." We can moderate exactly how we want.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cons:&lt;/strong&gt; It requires maintenance, updates, and server management. Plus, asking users to create &lt;em&gt;another&lt;/em&gt; account on a third-party site is a significant barrier to entry.&lt;/p&gt;




&lt;h2&gt;
  
  
  So what’s the verdict?
&lt;/h2&gt;

&lt;p&gt;We’re still torn, but we’re leaning toward &lt;strong&gt;GitHub Discussions&lt;/strong&gt;. From a maintainer's point of view, the integration into our existing workflow is just too good to ignore. It keeps everything in one place and doesn't add "server maintenance" to an already busy schedule.&lt;/p&gt;

&lt;p&gt;As for Discord? We’re going to pivot it back to what it was meant to be: a chat community. We’ll be more approachable there for direct messaging and quick chats, but the "knowledge" will live in the open.&lt;/p&gt;

&lt;p&gt;I’ll keep you posted on what we decide. Hopefully, this gives you some insight into the messy reality of community building in the open-source world.&lt;/p&gt;




&lt;p&gt;If you liked this post, feel free to follow me here on Dev.to, over on &lt;a href="https://bsky.app/profile/bdbch.com" rel="noopener noreferrer"&gt;Bluesky&lt;/a&gt; or on &lt;a href="https://github.com/bdbch" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>community</category>
      <category>developers</category>
      <category>discuss</category>
      <category>opensource</category>
    </item>
    <item>
      <title>This new HTML attribute will help you with loading states</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Sat, 01 Jul 2023 14:57:50 +0000</pubDate>
      <link>https://forem.com/bdbchgg/this-new-html-attribute-will-help-you-with-loading-states-3c93</link>
      <guid>https://forem.com/bdbchgg/this-new-html-attribute-will-help-you-with-loading-states-3c93</guid>
      <description>&lt;p&gt;Staying up to date with the latest developments in our standard web languages can be challenging, isn't it? However, I recently came across a new feature that proves to be immensely helpful for several use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new &lt;code&gt;inert&lt;/code&gt; attribute
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;inert&lt;/code&gt; attribute is a powerful new boolean attribute designed to provide precise control over the interactivity of an element. Its functionality allows developers to effortlessly determine when an element should be interactive or non-interactive, so no more &lt;code&gt;user-select: none&lt;/code&gt; or &lt;code&gt;pointer-events: none&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best thing about this&lt;/strong&gt;: Additionally, the &lt;code&gt;inert&lt;/code&gt; attribute serves as an event and event bubbling inhibitor, while also deactivating focusing elements. This remarkable feature eliminates the need to individually disable children or manage event handlers on the element itself!&lt;/p&gt;

&lt;h2&gt;
  
  
  What could this be used for?
&lt;/h2&gt;

&lt;p&gt;One of the primary applications that immediately comes to mind is utilizing the &lt;code&gt;inert&lt;/code&gt; attribute for form elements. Consider a scenario where you have a form that submits data via fetch. Previously, you would have had to individually disable each input element or the entire form while also taking measures to prevent events from being triggered by the form or its inputs.&lt;/p&gt;

&lt;p&gt;Now, with the introduction of the &lt;code&gt;inert&lt;/code&gt; attribute, achieving this functionality is incredibly simple. By just adding &lt;code&gt;&amp;lt;form inert&amp;gt;&lt;/code&gt; to the form element, you can effectively disable any interactive behavior associated with it during the submission process.&lt;/p&gt;

&lt;p&gt;Furthermore, leveraging the inert attribute opens up exciting possibilities for user interface design. You could opt to style the elements with the &lt;code&gt;inert&lt;/code&gt; attribute as transparent, giving users a clear visual cue that these elements are currently non-interactive. This enhances user understanding and provides a more intuitive user experience overall.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&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;form&lt;/span&gt; &lt;span class="na"&gt;inert&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- your form content here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;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 css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.3&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="nt"&gt;form&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;inert&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;loading&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Further reads
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Sharing your Tailwind Configuration between Monorepo Packages</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Fri, 23 Jun 2023 20:45:42 +0000</pubDate>
      <link>https://forem.com/bdbchgg/sharing-your-tailwind-configuration-between-monorepo-packages-4o5k</link>
      <guid>https://forem.com/bdbchgg/sharing-your-tailwind-configuration-between-monorepo-packages-4o5k</guid>
      <description>&lt;p&gt;In this post, you will learn how to share your Tailwind configuration between multiple packages inside a monorepo. It's important to note that the example provided here uses NPM workspaces, and while it may not be directly applicable to other solutions like Yarn, PNPM workspaces, Lerna, or Nx, the principles discussed can still be helpful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Tailwind Monorepo Setup
&lt;/h2&gt;

&lt;p&gt;Let's begin by examining the example project setup we'll be using for this explanation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- packages
  - ui
  - web
- package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we have two packages. The &lt;code&gt;ui&lt;/code&gt; package represents the UI component package from which we export all our React components. It will also serve as the location for our Tailwind configuration, which we want to import into our &lt;code&gt;web&lt;/code&gt; package. Keep in mind that this approach can also be extended to other workspace packages within your monorepo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Tailwind
&lt;/h2&gt;

&lt;p&gt;Before we dive into the specifics of sharing the Tailwind configuration, let's make sure we have the necessary setup in place. In this example, we'll be using Vite to generate our React application. You can follow the Tailwind setup as described in &lt;a href="https://tailwindcss.com/docs/guides/vite" rel="noopener noreferrer"&gt;their documentation&lt;/a&gt; to get started. Once you've run all the necessary commands, your &lt;code&gt;web&lt;/code&gt; directory should contain the following files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- postcss.config.js
- tailwind.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Moving the Theming Information
&lt;/h2&gt;

&lt;p&gt;With our initial setup complete, we can now proceed to move the theming configuration out of the &lt;code&gt;web&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;To achieve this, start by copying the theme block from your Tailwind configuration file located at &lt;code&gt;packages/web/tailwind.config.js&lt;/code&gt;. Create a &lt;strong&gt;new file&lt;/strong&gt; at &lt;code&gt;packages/ui/tailwind.config.js&lt;/code&gt;, and paste the copied theme block into it.&lt;/p&gt;

&lt;p&gt;It's important to name the config file &lt;code&gt;tailwind.config.js&lt;/code&gt; so that developer tools can parse your theme from the UI package as well.&lt;/p&gt;

&lt;p&gt;Your files should now look like this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;code&gt;packages/web/tailwind.config.js&lt;/code&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @type {import('tailwindcss').Config} */&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="na"&gt;content&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;./src/**/*.{js,jsx,ts,tsx}&lt;/span&gt;&lt;span class="dl"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;packages/ui/tailwind.config.js&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @type {import('tailwindcss').Config} */&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="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... your theme configuration&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 can see, inside our UI package, we only include the theming information. This approach is beneficial because we don't want to configure plugins globally since the UI project lacks a build process and won't process the plugins.&lt;/p&gt;

&lt;p&gt;While it might be tempting to include this configuration directly in your &lt;code&gt;web&lt;/code&gt; project, it's recommended to keep the plugins in separate projects.&lt;/p&gt;

&lt;p&gt;Now, let's include our theme from &lt;code&gt;ui&lt;/code&gt; in our &lt;code&gt;web&lt;/code&gt; configuration. Add the following line to &lt;code&gt;packages/web/tailwind.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;config&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;../ui/tailwind.config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, you need to allow Tailwind to watch your UI components and the Tailwind configuration file. This ensures that your build process can update your external theme configuration.&lt;/p&gt;

&lt;p&gt;To do this, add the following lines to the content array in &lt;code&gt;packages/web/tailwind.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&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="c1"&gt;// paste it below your normal content configuration&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../ui/**/*.{js,jsx,ts,tsx}&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;../ui/tailwind.config.js&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila! Your project should now pick up the external Tailwind configuration correctly, enabling you to share your theme across multiple projects.&lt;/p&gt;

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

&lt;p&gt;Thank you for reading this post. I hope you found it helpful! If you enjoyed this content and would like to read more, feel free to follow me on &lt;a href="https://twitter.com/idocodeandstuff" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and &lt;a href="https://github.com/bdbch" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're in need of a solid editor library for your next project, be sure to check out &lt;a href="https://tiptap.dev/" rel="noopener noreferrer"&gt;Tiptap&lt;/a&gt;. It's an open-source project, and we always appreciate feedback and contributions!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tailwindcss</category>
      <category>typescript</category>
      <category>react</category>
    </item>
    <item>
      <title>Apollo GraphQL Question: How to handle invalid network requests for mutations with optimistic UI?</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Wed, 09 Oct 2019 13:34:46 +0000</pubDate>
      <link>https://forem.com/bdbchgg/apollo-graphql-question-how-to-handle-invalid-network-requests-for-mutations-with-optimistic-ui-2mn3</link>
      <guid>https://forem.com/bdbchgg/apollo-graphql-question-how-to-handle-invalid-network-requests-for-mutations-with-optimistic-ui-2mn3</guid>
      <description>&lt;p&gt;Hey fellow dev.to readers and writers! Today I have a quick question regarding Apollo GraphQL.&lt;/p&gt;

&lt;p&gt;I'm currently working on an offline support feature so we can schedule mutations offline and show optimistic UI responses for them while the server does not respond.&lt;/p&gt;

&lt;p&gt;That works fine while being offline, so everytime I submit a chat message, I get an immediate response from the Optimistic UI cache but if I go offline and send messages, I won't get any optimistic UI responses if the network requests are failing.&lt;/p&gt;

&lt;p&gt;Am I missing something crucial on that concept?&lt;/p&gt;

&lt;p&gt;Would love to hear from you!&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>apollo</category>
      <category>question</category>
    </item>
    <item>
      <title>How to get react-native-push-notifications to work with React Native &gt;= 0.60</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Thu, 25 Jul 2019 13:38:14 +0000</pubDate>
      <link>https://forem.com/bdbchgg/how-to-get-react-native-push-notifications-to-work-with-react-native-0-60-e20</link>
      <guid>https://forem.com/bdbchgg/how-to-get-react-native-push-notifications-to-work-with-react-native-0-60-e20</guid>
      <description>&lt;p&gt;Hey! So I spent almost the whole day fiddling around with &lt;a href="https://github.com/zo0r/react-native-push-notification" rel="noopener noreferrer"&gt;react-native-push-notifications&lt;/a&gt; which has a really slow update cycle.&lt;/p&gt;

&lt;p&gt;Besides linking the package via react-native and setting up the native code in iOS it works fine out of the box on iOS devices.&lt;/p&gt;

&lt;p&gt;On Android on the other hand, the currently available npm version of the package will break with any react native project using &lt;strong&gt;androidx&lt;/strong&gt;. Thats because androidx dropped the old module structure from &lt;code&gt;android.support&lt;/code&gt; to &lt;code&gt;androidx.&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Funny thing is: the fix is already commited to the master. So you can just simply install the repository from Github via&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;git+https://git@github.com/zo0r/react-native-push-notification &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should have the fixed version in your repository! Follow the android setup guide as described in the README.&lt;/p&gt;

&lt;p&gt;The only thing you now need to do is to add a Firebase and Google Play Services version to your apps &lt;code&gt;build.gradle&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the following values to your &lt;code&gt;ext&lt;/code&gt; values just below the &lt;code&gt;supportLibVersion&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;googlePlayServicesVersion = "16.1.0"
firebaseVersion = "17.3.4"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;my &lt;code&gt;ext&lt;/code&gt; configuration now 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;ext {
    buildToolsVersion = "28.0.3"
    minSdkVersion = 16
    compileSdkVersion = 28
    targetSdkVersion = 28
    supportLibVersion = "28.0.0"
    googlePlayServicesVersion = "16.1.0"
    firebaseVersion = "17.3.4"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should be able to build your android project and run your app in the simulator!&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>help</category>
    </item>
    <item>
      <title>react-devto: React Hooks for Dev.to</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Mon, 22 Jul 2019 17:54:56 +0000</pubDate>
      <link>https://forem.com/bdbchgg/react-devto-react-hooks-for-dev-to-105</link>
      <guid>https://forem.com/bdbchgg/react-devto-react-hooks-for-dev-to-105</guid>
      <description>&lt;p&gt;Hello dear dev.to community!&lt;/p&gt;

&lt;p&gt;A few days ago I pushed my React hooks library for dev.to which can be used to fetch articles and user information.&lt;/p&gt;

&lt;p&gt;You can find it over &lt;a href="https://github.com/bdbch/react-devto" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bdbch.github.io/react-devto/" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @d2k/react-devto &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage:
&lt;/h3&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;useArticles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;useFollowSuggestions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;useTags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;useUser&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;@d2k/react-devto&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;MyComponent&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;// useArticles(page, tag, username)&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;articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useArticles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// useFollowSuggestions()&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;suggestions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFollowSuggestions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// useTags(page)&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;tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTags&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// useUser(username, id)&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bdbch&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>showdev</category>
      <category>react</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Webdevelopment for Beginners 03 - Bring in some action</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Sun, 21 Jul 2019 23:56:32 +0000</pubDate>
      <link>https://forem.com/bdbchgg/webdevelopment-for-beginners-03-bring-in-some-action-2e0b</link>
      <guid>https://forem.com/bdbchgg/webdevelopment-for-beginners-03-bring-in-some-action-2e0b</guid>
      <description>&lt;p&gt;Hey, welcome back to my Webdevelopment for Begginers guide. Today we'll learn how to add images, lists and YouTube videos to our page!&lt;/p&gt;

&lt;h1&gt;
  
  
  Lists
&lt;/h1&gt;

&lt;p&gt;So lets start with the simplest of the new things to learn: &lt;strong&gt;Lists&lt;/strong&gt;. Lists can be used everywhere where content is listed. That could be a simple recipe list, a list of users or a navigation.&lt;/p&gt;

&lt;p&gt;Yes a navigation is also a list of links, so using a list for your navigation items would be the best, semantic solution.&lt;/p&gt;

&lt;p&gt;Creating lists is very easy. This is how two lists would look like in code:&lt;br&gt;
&lt;/p&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;Hello world&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;Tutorial demo website&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
      This is a tutorial demo page for my dev.to beginner tutorial about
      HTML.&lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      You can find my profile
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://dev.to/bdbch/"&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;here&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Twitter&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Github&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Dev.to&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Spectrum.chat&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ol&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;First step&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Do something else in the second step&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Another step which is the third&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ol&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;p&gt;As you can see we have three new tags. &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;: Unordered lists
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ul&lt;/code&gt; stands for unordered list. This means our list will not be numbered or ordered in any way. It's not self-closing and requires content.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;: Ordered lists
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ol&lt;/code&gt; stands for ordered list. This means our list will be ordered in a logical way. This could be a numbered list, or a alphabetic list.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;: List items
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;li&lt;/code&gt; stands for list item and is required to build lists. This element must always be used in &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; lists. Otherwise you won't be able to create semantic items in your list.&lt;/p&gt;

&lt;p&gt;Now how does our website look like?&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%2Faotyyfatc7r5t261t3ri.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%2Faotyyfatc7r5t261t3ri.png" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome!&lt;/p&gt;

&lt;h3&gt;
  
  
  Nesting lists
&lt;/h3&gt;

&lt;p&gt;You can nest lists inside each other. To do this, you need to create a new &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; inside a &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; list element. A nested list would look like this in code:&lt;br&gt;
&lt;/p&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;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
    Twitter
    &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;List item&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;List item&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;List item&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;List item&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Github&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Dev.to&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Spectrum.chat&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will result in something like this:&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%2Fmhzvjo0uvau1x1uyxhur.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%2Fmhzvjo0uvau1x1uyxhur.png" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it works as expected.&lt;/p&gt;

&lt;h1&gt;
  
  
  Images
&lt;/h1&gt;

&lt;p&gt;So now it gets interesting. Lets insert an image into our website. But how do we do this? Luckily we have the tag &lt;code&gt;img&lt;/code&gt; at our disposal. The img tag requires a few attributes to run correctly but it really isn't that complicated.&lt;/p&gt;

&lt;p&gt;Lets see how to use an image. We're using &lt;a href="https://picsum.photos/" rel="noopener noreferrer"&gt;unsplash.it&lt;/a&gt; for our pictures:&lt;br&gt;
&lt;/p&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;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unsplash.it/500/500"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Image description for screen readers"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that we used the &lt;code&gt;src&lt;/code&gt; and &lt;code&gt;alt&lt;/code&gt; attributes for our img tag.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;src&lt;/code&gt; stands for source and requires a link to a valid image.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;alt&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;alt&lt;/code&gt; stands for alternative and means the image description if the image can't be loaded or a person can't see the image and requires a screenreader.&lt;/p&gt;

&lt;p&gt;Now lets see the page output, right?&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%2Fmxddgckeit6ginq8n3m6.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%2Fmxddgckeit6ginq8n3m6.png" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wasn't that hard, right?&lt;/p&gt;

&lt;h1&gt;
  
  
  YouTube Video Embed
&lt;/h1&gt;

&lt;p&gt;Now lets get some action into the page! Let's embed a video from YouTube! For that you'll need the embed code. You can find it on a YouTube video when you want to share it. Lets add the embed code to our website.&lt;br&gt;
&lt;/p&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;iframe&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"560"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"315"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.youtube.com/embed/9SBNCYkSceU"&lt;/span&gt; &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;allow=&lt;/span&gt;&lt;span class="s"&gt;"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"&lt;/span&gt; &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that YouTube uses a tag called &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;. A iframe is a frame which can embed external websites in your document. It even uses the same &lt;code&gt;src&lt;/code&gt; attribute as the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;The width and height are defined via the width and height attributes. All other attributes are specific attributes for iframe permissions and if the iframe can go fullscreen.&lt;/p&gt;

&lt;p&gt;Now if we open our website with this embed, it will look like this:&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%2Fv67232jraf8a7k55mt14.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%2Fv67232jraf8a7k55mt14.gif" width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now we have an embedded version of YouTube in our HTML document which will start on click. Easy!&lt;/p&gt;

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

&lt;p&gt;Now that we played around with tags and attributes, I think it's time to build a website with multiple pages and create a navigation. Check out the next post if you want to learn more about it!&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Webdevelopment for Beginners 02 - Lets start a project</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Sun, 21 Jul 2019 13:08:53 +0000</pubDate>
      <link>https://forem.com/bdbchgg/webdevelopment-for-beginners-lets-start-a-project-m65</link>
      <guid>https://forem.com/bdbchgg/webdevelopment-for-beginners-lets-start-a-project-m65</guid>
      <description>&lt;p&gt;Welcome to my second part of the &lt;strong&gt;Webdevelopment for Beginners&lt;/strong&gt; series! In this part we will start creating our first own project and write down some code. But before we write code, I'll explain to you what kind of code you're actually going to write.&lt;/p&gt;

&lt;h1&gt;
  
  
  Meet HTML
&lt;/h1&gt;

&lt;p&gt;HTML is a markup language used by browsers to create a "tree structure" of nodes which will be rendered. It's the core of every website and you won't come around HTML if you want to learn webdevelopment. But it's actually very easy &lt;strong&gt;if you can think in &lt;del&gt;portals&lt;/del&gt; boxes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A HTML file is made out of a lot of &lt;strong&gt;Tags&lt;/strong&gt;.&lt;br&gt;
&lt;/p&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;header&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello world&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I used two tags called &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt;. &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; is used to tell your browser that it's a header element, while &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; is a shorthand for &lt;strong&gt;paragraph&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some browsers bring styles for their elements by default (for example headlines, paragraphs and lists always have default styles determined by the browser). A &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; element on the other hand does not provide any styles and will behave the same as any other element which will not have styles provided by the browser.&lt;/p&gt;

&lt;p&gt;So this code would print out a header element with a paragraph containing "Hello world" in it.&lt;/p&gt;

&lt;h1&gt;
  
  
  What kind of Tags are out there?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;A TON&lt;/strong&gt;. With HTML5 we received a lot of new tags to play around with. Most of them are &lt;strong&gt;semantic&lt;/strong&gt; tags. Semantic tags are used to tell your browser what kind of element something is. &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; for example tells your browser, that it's a header element. This information can also be helpful for screen readers, search engines and more).&lt;/p&gt;

&lt;p&gt;You can see a full list of HTML elements on the &lt;a href="https://developer.mozilla.org/docs/Web/HTML/Element" rel="noopener noreferrer"&gt;MDN (Mozilla Developer Network)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As you can see there are plenty of them and each of them has their own role. In this tutorial you will learn a few elements you'll need a lot.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lets start creating a website
&lt;/h1&gt;

&lt;p&gt;Enough talk about HTML, lets create a project and use it. I'd recommend creating a folder just for your website. I'll call mine &lt;code&gt;example-website&lt;/code&gt;. Inside this new  folder, we will create a file called &lt;code&gt;index.html&lt;/code&gt;. The index file is always the first page loaded by most of the webservers out there so &lt;code&gt;index.html&lt;/code&gt; would be your homepage.&lt;/p&gt;

&lt;p&gt;My workspace in Visual Studio Code now looks like this.&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%2Fk8m7fs1gu02w8jhxo3o3.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%2Fk8m7fs1gu02w8jhxo3o3.png" width="800" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now open your browser and drag in your &lt;code&gt;index.html&lt;/code&gt; file to open it.&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%2Fwcfadzn586rund3wdra5.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%2Fwcfadzn586rund3wdra5.png" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well this looks boring. In Firefox and Chrome you can open the developer tools by pressing F12 or Command+Shift+I. For me it looks like this:&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%2Fjk27clocmxkm0vsykfa3.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%2Fjk27clocmxkm0vsykfa3.png" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, we have some code on the right side of the screen, but we actually didn't write a line of code yet. How can this be? The reason for that is, that every HTML file is required to have a &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; tag is the wrapper for your whole document. Everything lives in this file and it's the &lt;strong&gt;root&lt;/strong&gt; node for your document.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag is a place for meta informations like the page title, descriptions and other informations for your browser. It's also the place where most of the styling assets will be loaded at.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag is the place, where the party actually is going on. It's the content of your website that will be visible to your visitors. Since every website requires these tags, we'll start writing them on our own in our &lt;code&gt;index.html&lt;/code&gt;.&lt;br&gt;
&lt;/p&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;Hello world&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;/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;p&gt;The formatting is just my own choice and best practice defined by prettier. You can write your code as you like but you can try to stick to my style of indentation if you'd like to.&lt;/p&gt;

&lt;p&gt;As you can see, we defined the html, head and body tags of our website but I also added a &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; tag with &lt;em&gt;Hello world&lt;/em&gt; in it. What does it do? Well reload your website in your browser and see it by yourself!&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%2Feun84ppt6ivn4j5wvlfn.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%2Feun84ppt6ivn4j5wvlfn.png" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, we now have a title for our website defined in the browser tab. The &lt;code&gt;title&lt;/code&gt; tag is a tag with meta informations for your browser and also search engines or crawlers.&lt;/p&gt;

&lt;p&gt;But your page is still white. Meh. How about we put on a title and some description of what this website is?&lt;br&gt;
&lt;/p&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;Hello world&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;Tutorial demo website&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is a tutorial demo page for my dev.to beginner tutorial about HTML.&lt;span class="nt"&gt;&amp;lt;/p&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;p&gt;We added in a &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag here. We already talked about the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag which means paragraph. But what does the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; mean? The &lt;code&gt;h&lt;/code&gt; stands for headline and the number behind it is the type of headline.&lt;/p&gt;

&lt;p&gt;If you think about it as a Word document, you would have 6 types of headlines. Each has it's own priority. &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; to &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt; would mean that &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; has the &lt;strong&gt;highest priority&lt;/strong&gt; and should be used for page titles while &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt; has the &lt;strong&gt;lowest priority&lt;/strong&gt; and should be used for very small section headlines.&lt;/p&gt;

&lt;p&gt;If we now load our page, this is what we should see:&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%2Fwoqyklre4i8bnj87rmrn.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%2Fwoqyklre4i8bnj87rmrn.png" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool! Now you have your first document written in HTML. Quite boring but at least something.&lt;/p&gt;

&lt;p&gt;Wouldn't it be cool, if we could also add a link to your dev.to profile? Lets try this out!&lt;br&gt;
&lt;/p&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;Hello world&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;Tutorial demo website&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    This is a tutorial demo page for my dev.to beginner tutorial about HTML.&lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    You can find my profile &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://dev.to/bdbch/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;here&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/p&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;p&gt;What is going on? We reformatted the paragraph a bit. As you can see, we're using a &lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt; here. Why is it written in this strange fashion? It's a &lt;strong&gt;self-closing&lt;/strong&gt; tag. &lt;code&gt;br&lt;/code&gt; stands for a line &lt;strong&gt;br&lt;/strong&gt;eak which means, it can't have content itself. If a tag can't have it's own child element, it's a self closing element and can be written like this: &lt;code&gt;&amp;lt;tag /&amp;gt;&lt;/code&gt;. Another example for this would be images which I will show you afterwards.&lt;/p&gt;

&lt;p&gt;You can see another new tag. &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; with some strange giberrish afterwards. This gibberish is an &lt;code&gt;attribute&lt;/code&gt;. HTML tags can have many of them and they modify the behaviour of a tag.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag is an anchor (or link) which means it can link your website to another page on click. Since you have to tell the anchor where to link to, you can use &lt;strong&gt;attributes&lt;/strong&gt; to give it the information it needs.&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag would now link to my dev.to profile. Let's give it a try!&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%2Fsfodwghphcvvu1yf56mq.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%2Fsfodwghphcvvu1yf56mq.gif" width="1284" height="978"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that works! Awesome. But it replaces the current tab 🤔, how could we fix t hat? Let's bring in another attribute called &lt;code&gt;target&lt;/code&gt;. Both attributes are exclusive to the anchor tag. Target defines where the browser should open the link.&lt;br&gt;
&lt;/p&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;Hello world&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;Tutorial demo website&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    This is a tutorial demo page for my dev.to beginner tutorial about HTML.&lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    You can find my profile &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://dev.to/bdbch/"&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;here&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/p&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;p&gt;We set the &lt;code&gt;target&lt;/code&gt; attribute to &lt;code&gt;_blank&lt;/code&gt;. This means it will open in a new window. Since browsers now have tabs, it will open in a new tab instead.&lt;/p&gt;

&lt;p&gt;You can see all kind of attributes for the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Attributes" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&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%2Fgka8079qwx131t5iutdt.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%2Fgka8079qwx131t5iutdt.gif" width="1284" height="978"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There we go. Now the link opens in a new tab.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I think this should be enough to get the first concepts of HTML. My suggestion for you would be to try around a few elements from &lt;a href="https://developer.mozilla.org/docs/Web/HTML/Element" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Play with them and their attributes to learn a bit more about them.&lt;/p&gt;

&lt;p&gt;In the next part we will be adding &lt;strong&gt;images&lt;/strong&gt;, &lt;strong&gt;lists&lt;/strong&gt; and embed a YouTube player!&lt;/p&gt;

&lt;p&gt;See you next time.&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Webdevelopment for Beginners 01 - How to get started</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Sun, 21 Jul 2019 13:08:42 +0000</pubDate>
      <link>https://forem.com/bdbchgg/webdevelopment-for-beginners-how-to-get-started-59m</link>
      <guid>https://forem.com/bdbchgg/webdevelopment-for-beginners-how-to-get-started-59m</guid>
      <description>&lt;p&gt;Welcome to my second tutorial series called &lt;strong&gt;Webdevelopment for Beginners&lt;/strong&gt;. This series will be written for beginners trying to get into Webdevelopment but don't know where to start. I'll try to keep everything as simple as possible and link resources to learn more.&lt;/p&gt;

&lt;p&gt;In the span of this tutorial you will read about the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The tools used for webdevelopment&lt;/li&gt;
&lt;li&gt;Awesome learning resources and links&lt;/li&gt;
&lt;li&gt;What is HTML and how to write it&lt;/li&gt;
&lt;li&gt;What is CSS and how to write it&lt;/li&gt;
&lt;li&gt;The box layout and how layouting in browsers work&lt;/li&gt;
&lt;li&gt;How to combine HTML and CSS to create simple page layouts&lt;/li&gt;
&lt;li&gt;How to host a website&lt;/li&gt;
&lt;li&gt;What is JavaScript and how to write it&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Lets get started: What tools do you need to start developing websites?
&lt;/h1&gt;

&lt;p&gt;Luckily you really don't need any tools to begin with webdevelopment. You could fire up your notepad or any other text editor and start writing code which is okay but for beginners I suggest using tools that can help you memorizing code without looking up a tutorial or documentation every 5 seconds.&lt;/p&gt;

&lt;p&gt;For that, I'd suggest &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; developed by Microsoft. It supports autocompletion for code and helps you with suggestions for code you write.&lt;/p&gt;

&lt;p&gt;I'd advise against any tool that supports WYSIWYG (What you see is what you get). Visual editors are bad for you and won't help you with your future development because it generates really bad code 90% of the time and won't help you actually learning the code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But if I can use a visual editor, why should I learn to code?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I said visual editors generate code &lt;strong&gt;really bad&lt;/strong&gt;. That could change in a few years with AI and Machine Learning but even then editors never really work well with logic implementations.&lt;/p&gt;

&lt;p&gt;Also it's way more fun writing code and seeing the output working fine. :)&lt;/p&gt;

&lt;h1&gt;
  
  
  Any other tools needed?
&lt;/h1&gt;

&lt;p&gt;You actually just need a browser. I'd suggest using Chrome or Firefox. Chrome has superior development tools when it comes to editing styles, responsive development, debugging JavaScript or analyzing your page but will watch you (since it's Google).&lt;/p&gt;

&lt;p&gt;If you are a privacy advocate I'd suggest using Firefox. It also has good styling devtools, a really good layouting helper and other nice tools. Just the debugger and analyzing tools are behind Google Chrome.&lt;/p&gt;

&lt;p&gt;After having your preferred tools setup and running, you're ready to write your first small website.&lt;/p&gt;

&lt;p&gt;Read about it in my next post in this series!&lt;/p&gt;

</description>
      <category>html</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A quick explanation on useEffect</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Sat, 20 Jul 2019 23:35:43 +0000</pubDate>
      <link>https://forem.com/bdbchgg/a-quick-explanation-on-useeffect-2nn9</link>
      <guid>https://forem.com/bdbchgg/a-quick-explanation-on-useeffect-2nn9</guid>
      <description>&lt;p&gt;I got asked if I could write a quick explanation on the useEffect hook provided by React and thought "Sure, that should help a few people!".&lt;/p&gt;

&lt;p&gt;useEffect can behave like &lt;code&gt;componentDidMount&lt;/code&gt; &lt;code&gt;shouldComponentUpdate&lt;/code&gt; and &lt;code&gt;componentWillUnmount&lt;/code&gt; in one function if you set it up correctly. In this post I'll show you a few ways to replicate different lifecycle behaviours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep in mind that useEffect uses the second argument &lt;code&gt;dependencies&lt;/code&gt; as a performance tool&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is an interesting read about how you can write your hooks in general even without dependencies:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/samsch_org/effects-are-not-lifecycles-551o"&gt;https://dev.to/samsch_org/effects-are-not-lifecycles-551o&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example as &lt;code&gt;componentDidMount&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;First you can write an Effect that will just run once when the component mounted and will never run again:&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;useEffect&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I was mounted and will not run again!&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="p"&gt;[])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important here is the empty array as a second argument. The second argument of useEffect can be used to watch properties for changes. See the following.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example as &lt;code&gt;shouldComponentUpdate&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;useEffect can also help with watchers on your properties so you can run it everytime a specific value is updated. Let's say we have a prop called "name" and our component should update something via effect everytime the name prop changes you could do it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Page of &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;name&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="nx"&gt;props&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My name is &lt;span class="si"&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;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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;You can see that we passed &lt;code&gt;props.name&lt;/code&gt; into the array in the second argument. This will now cause the effect to always run again when the name changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note&lt;/strong&gt;: You should always set the second argument because otherwise you can run into render loops.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example as &lt;code&gt;componentWillUnmount&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;useEffect can also be used to run code when the component dismounts. This is effective for subscriptions or other listeners (Websockets for example).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bookSubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&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;// stop the subscription if it already exists&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bookSubscription&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;bookSubscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;bookSubscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;// start a new subscription&lt;/span&gt;
  &lt;span class="nx"&gt;bookSubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;startBookSubscription&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;bookId&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;bookId&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;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// stop the subscription when the component unmounts&lt;/span&gt;
    &lt;span class="nx"&gt;bookSubscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that now we used all options available. This code will now&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start a new subscription when the component was mounted&lt;/li&gt;
&lt;li&gt;Update the subscription with the new bookId when the bookId prop changes&lt;/li&gt;
&lt;li&gt;unsubscribe the subscription when the component gets unmounted.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can run logic whenever the component unmounts by returning a function in your effect.&lt;/p&gt;




&lt;p&gt;I hope this quick post was helpful to you and helps you with further development. If you have questions, let me know!&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>React Hooks for Data Part 1 - Fetching Data</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Fri, 19 Jul 2019 22:03:15 +0000</pubDate>
      <link>https://forem.com/bdbchgg/react-hooks-for-data-part-1-fetching-data-28ge</link>
      <guid>https://forem.com/bdbchgg/react-hooks-for-data-part-1-fetching-data-28ge</guid>
      <description>&lt;p&gt;So the large hype on React Hooks is over and the community isn't talking about them that much anymore. But seriously hooks are beasts. In this post I'll explain how you can use React Hooks to fetch and submit data to any API (I'll use REST in this guide).&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing your own hook
&lt;/h2&gt;

&lt;p&gt;We'll start with writing our first hook to fetch books from an API. Here is the example code:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// The hook is just a simple function which we can export&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;useFetchBooks&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;// First we define the necessary states for our hook&lt;/span&gt;
  &lt;span class="c1"&gt;// this includes book, the loading state and potential errors&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;books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBooks&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="c1"&gt;// useEffect can be compared to componentDidMount,&lt;/span&gt;
  &lt;span class="c1"&gt;// componentDidUpdate and componentDidUnmount&lt;/span&gt;
  &lt;span class="c1"&gt;// read more about useEffect here:&lt;/span&gt;
  &lt;span class="c1"&gt;// https://reactjs.org/docs/hooks-effect.html&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&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;// First we set the loading and error states&lt;/span&gt;
    &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;setError&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://library.com/api/books&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;setBooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;setBooks&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;Now this looks complicated but really it isn't. Remove the comments and it will be a really short function which fetches data and updates states.&lt;/p&gt;

&lt;p&gt;Now that we have the hook, we can use it in a component like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&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;useFetchBooks&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;./utils/hooks&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;BookList&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;// use your own hook to load the data you need&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;books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFetchBooks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt; 
        &lt;span class="nx"&gt;books&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="nx"&gt;books&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;book&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
      &lt;span class="si"&gt;}&lt;/span&gt; 
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;BookList&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use parameters in your hook
&lt;/h2&gt;

&lt;p&gt;Now our hook works fine but it's still a bit stupid. Lets say you want your users to be able to search for books in the list. You could do it 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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Note here the new parameter we pass into the hook called "search"&lt;/span&gt;
&lt;span class="c1"&gt;// this will be used to search the api for specific books&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;useFetchBooks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;search&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;books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBooks&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="nf"&gt;useEffect&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="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;setError&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="c1"&gt;// Change the apiUrl according to the search string&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
      &lt;span class="s2"&gt;`https://library.com/api/books?search=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;search&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="s1"&gt;https://library.com/api/books&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;setBooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;setBooks&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="c1"&gt;// This is important. We pass the new search parameter into&lt;/span&gt;
  &lt;span class="c1"&gt;// the empty array we had before. This means, the effect&lt;/span&gt;
  &lt;span class="c1"&gt;// will run again if this parameter changes&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;search&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="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;Now you can use the hook like this in your component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFetchBooks&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;search&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should be enough for part 1 and should clarify how to use hooks to fetch data from any API.&lt;/p&gt;

&lt;p&gt;I'll update this post with a link to part 2 as soon as I'm done with it.&lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Automatically watch queries in Apollo GraphQL</title>
      <dc:creator>Dominik Biedebach</dc:creator>
      <pubDate>Fri, 19 Jul 2019 15:14:06 +0000</pubDate>
      <link>https://forem.com/bdbchgg/automatically-watch-queries-in-apollo-graphql-n45</link>
      <guid>https://forem.com/bdbchgg/automatically-watch-queries-in-apollo-graphql-n45</guid>
      <description>&lt;p&gt;I just worked on one of our hooks that fetches data from our Apollo GraphQL server, but I noticed that my data won't be updated in the local cache when the current subscription is not open.&lt;/p&gt;

&lt;p&gt;This is how my code looked like before:&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;chatId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123456&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;query&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="nx"&gt;GET_CHAT_MESSAGES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chatId&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&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;// do stuff here&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query would not update after being run once because Apollo saves all queries locally without knowing about potential changes.&lt;/p&gt;

&lt;p&gt;When mutations were made, the chat view would still show an old state, even when my subscription would rewrite the cache.&lt;/p&gt;

&lt;p&gt;What I had to do was using &lt;code&gt;client.watchQuery&lt;/code&gt; instead of &lt;code&gt;client.query&lt;/code&gt;. watchQuery allows you to watch a query for potential changes via mutations and re-run the query if needed. It also allows you to use the 'cache-and-network' fetch policy.&lt;/p&gt;

&lt;p&gt;Now my code 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123456&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;querySubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;watchQuery&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="nx"&gt;GET_CHAT_MESSAGES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chatId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;fetchPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cache-and-network&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&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="c1"&gt;// do stuff },&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;Just make sure to disconnect the subscription if it is not needed anymore with &lt;code&gt;querySubscription.unsubscribe()&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>apollo</category>
      <category>graphql</category>
    </item>
  </channel>
</rss>
