<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Georgie</title>
    <description>The latest articles on DEV Community by Georgie (@georgeisiguzo).</description>
    <link>https://dev.to/georgeisiguzo</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%2F608276%2Fc3c509b3-6aca-4fe5-b92a-2d7354884822.jpg</url>
      <title>DEV Community: Georgie</title>
      <link>https://dev.to/georgeisiguzo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/georgeisiguzo"/>
    <language>en</language>
    <item>
      <title>I just finished building my Portfolio! Here are 3 key features I added</title>
      <dc:creator>Georgie</dc:creator>
      <pubDate>Tue, 19 Jul 2022 20:40:27 +0000</pubDate>
      <link>https://dev.to/georgeisiguzo/i-just-finished-building-my-portfolio-would-appreciate-feedback-3b6l</link>
      <guid>https://dev.to/georgeisiguzo/i-just-finished-building-my-portfolio-would-appreciate-feedback-3b6l</guid>
      <description>&lt;p&gt;I built it with ReactJS, TailwindCSS and HeadlessUI.&lt;/p&gt;

&lt;p&gt;See link to portfolio here: &lt;a href="https://www.georgeisiguzo.xyz/"&gt;https://www.georgeisiguzo.xyz/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3GJZZieK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ijuwdtxbgs452gaf6vs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3GJZZieK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ijuwdtxbgs452gaf6vs.gif" alt="my portfolio" width="880" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just in case you want to create something similar, I want to share how I added 3 key features to the portfolio.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Key Features
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pre-Loading Screen&lt;/li&gt;
&lt;li&gt;Transition&lt;/li&gt;
&lt;li&gt;Light/Dark Theme&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now let's begin.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're using TailwindCSS, what I'm about to show will be very applicable to you and if you aren't, I wonder why? 😁&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Pre-Loading Screen
&lt;/h2&gt;

&lt;p&gt;See the pre-loading screen below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oDefNoOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqyt0tm3mwgmx5fbfyrs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oDefNoOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqyt0tm3mwgmx5fbfyrs.gif" alt="preloader" width="880" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now before I show you how to add one to your portfolio or any other app, what's the essence of a preloader on your app?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Preloaders, particularly animated ones, look nice and provide a solid first impression - &lt;a href="https://medium.com/design-bootcamp/why-preloader-is-good-for-your-website-6814822ac1b1"&gt;bootcamp.uxdesign.cc&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not my words! Lol... But several notable tech portfolios do have them for example - &lt;a href="https://brittanychiang.com"&gt;brittanychiang&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to create a pre-loader in a ReactJS app:
&lt;/h3&gt;

&lt;p&gt;We will use functional components and React hooks for all examples in this article:&lt;/p&gt;

&lt;p&gt;This is the code to create a pre-loader:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useState } from "react"; // #1

function App() {
  const [isLoading, setIsLoading] = useState(true); // #2

// #3
  useEffect(() =&amp;gt; {
    const timer = setTimeout(() =&amp;gt; {
      setIsLoading(false);
    }, 5000);

    return () =&amp;gt; {
      clearTimeout(timer);
    };
  }, []);

  return (
    &amp;lt;div className="app"&amp;gt;
      {!isLoading &amp;amp;&amp;amp; ( // # 4
        &amp;lt;div className="flex flex-col h-screen"&amp;gt;
          {// put your main page content here}
        &amp;lt;/div&amp;gt;
        )
      }
      {isLoading &amp;amp;&amp;amp; ( // # 5
        &amp;lt;div className="flex flex-col h-screen"&amp;gt;
          {// put your preloader content here}
        &amp;lt;/div&amp;gt;
        )
      }
    &amp;lt;/div&amp;gt;
  )

}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;First we import React, &lt;code&gt;useState&lt;/code&gt;, and &lt;code&gt;useEffect&lt;/code&gt; hooks.&lt;/li&gt;
&lt;li&gt;Next we create a true/false (boolean) variable called &lt;code&gt;isLoading&lt;/code&gt; whose value will determine what will show on the page. The initial value for &lt;code&gt;isLoading&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We use the &lt;code&gt;useEffect&lt;/code&gt; hook to change the value of &lt;code&gt;isLoading&lt;/code&gt; after 5 secs using &lt;code&gt;setTimeout()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We use conditional rendering for #4 and #5 to determine how to show our preloader and the main content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Try it out. &lt;/p&gt;

&lt;p&gt;Complete the code snippet with your desired content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transition
&lt;/h2&gt;

&lt;p&gt;See how one section of my portfolio transitions to another below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2UtIjNBQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvwrx8seax7yzyf8mbl9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2UtIjNBQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvwrx8seax7yzyf8mbl9.gif" alt="transition.gif" width="880" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why add a transition between pages/sections?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Page transitions are animated transitions between pages that give websites that extra touch that distinguishes them as top-notch and worthy of a good browse. So, when applied correctly, it can give a sense of liveliness and help significantly with navigation - &lt;a href="https://orpetron.com/blog/page-transitions-to-enhance-ux/"&gt;orpetron.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yeah, page transitions make websites cool 😎&lt;/p&gt;

&lt;h3&gt;
  
  
  Now how can you add page transitions to your app?
&lt;/h3&gt;

&lt;p&gt;While there are other libraries you can use (and you can also use pure CSS), CSS is hard for me so I use HeadlessUI for transitions.&lt;/p&gt;

&lt;p&gt;Before using the code below, you will first need to install HeadlessUI using npm 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;npm install @headlessui/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Transition } from "@headlessui/react"; // #1

...
&amp;lt;Transition // #2
    show={true} // place a boolean variable here to determine when to show this component
    enter="transition ease-in-out duration-700 transform"
    enterFrom="translate-x-full"
    enterTo="translate-x-0"
    leave="transition ease-in-out duration-500 transform"
    leaveFrom="translate-x-0"
    leaveTo="translate-x-full"
    &amp;gt;
        {// place component content here}
&amp;lt;/Transition&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;First we import &lt;code&gt;Transition&lt;/code&gt; from HeadlessUI&lt;/li&gt;
&lt;li&gt;Next we can use &lt;code&gt;Transition&lt;/code&gt; anywhere in our app&lt;/li&gt;
&lt;li&gt;Take note of the values of each property (prop) of &lt;code&gt;Transition&lt;/code&gt; especially &lt;code&gt;show&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;show&lt;/code&gt; determine when the component inside &lt;code&gt;Transition&lt;/code&gt; will enter and when it will leave the user's screen.&lt;/li&gt;
&lt;li&gt;Other props like &lt;code&gt;enter&lt;/code&gt;, &lt;code&gt;leave&lt;/code&gt;, &lt;code&gt;enterTo&lt;/code&gt; etc determine the transition behavior of the component. How it will enter and leave the screen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See &lt;a href="https://headlessui.com/react/transition#component-api"&gt;HeadlessUI doc here&lt;/a&gt; to know how to tweak each prop.&lt;/p&gt;

&lt;p&gt;Let's use &lt;code&gt;Transition&lt;/code&gt; to render our preloader and main content like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useState } from "react"; // #1

function App() {
  const [isLoading, setIsLoading] = useState(true); // #2

// #3
  useEffect(() =&amp;gt; {
    const timer = setTimeout(() =&amp;gt; {
      setIsLoading(false);
    }, 5000);

    return () =&amp;gt; {
      clearTimeout(timer);
    };
  }, []);

  return (
    &amp;lt;div className="app"&amp;gt;
      &amp;lt;Transition
          show={!isLoading}
          enter="transition ease-in-out duration-700 transform"
          enterFrom="translate-x-full"
          enterTo="translate-x-0"
          leave="transition ease-in-out duration-500 transform"
          leaveFrom="translate-x-0"
          leaveTo="translate-x-full"
        &amp;gt;
          &amp;lt;div className="flex flex-col h-screen"&amp;gt;
            {// put your main page content here}
          &amp;lt;/div&amp;gt;
      &amp;lt;/Transition&amp;gt;
      &amp;lt;Transition
          show={isLoading}
          enter="transition ease-in-out duration-700 transform"
          enterFrom="translate-x-full"
          enterTo="translate-x-0"
          leave="transition ease-in-out duration-500 transform"
          leaveFrom="translate-x-0"
          leaveTo="translate-x-full"
        &amp;gt;
          &amp;lt;div className="flex flex-col h-screen"&amp;gt;
            {// put your preloader content here}
          &amp;lt;/div&amp;gt;
      &amp;lt;/Transition&amp;gt;
    &amp;lt;/div&amp;gt;
  )

}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;We used &lt;code&gt;Transition&lt;/code&gt; twice, one for the main content and the other for the preloader.&lt;/li&gt;
&lt;li&gt;We passed &lt;code&gt;isLoading&lt;/code&gt;(a boolean) as the value for the &lt;code&gt;show&lt;/code&gt; prop.&lt;/li&gt;
&lt;li&gt;For main content, the &lt;code&gt;show&lt;/code&gt; prop value is &lt;code&gt;!isLoading&lt;/code&gt;. We use &lt;code&gt;!&lt;/code&gt; before &lt;code&gt;isLoading&lt;/code&gt; meaning the opposite or inverse of the current value of &lt;code&gt;isLoading&lt;/code&gt;. &lt;code&gt;!&lt;/code&gt; also means not (i.e !isLoading means not isLoading) &lt;/li&gt;
&lt;li&gt;For the preloader, the &lt;code&gt;show&lt;/code&gt; prop value is &lt;code&gt;isLoading&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's just it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Light/Dark Theme
&lt;/h2&gt;

&lt;p&gt;Finally, changing themes from light to dark and vice versa.&lt;/p&gt;

&lt;p&gt;Why does your app need this feature?&lt;/p&gt;

&lt;p&gt;Let me answer without reference to an external source for once 😅&lt;/p&gt;

&lt;p&gt;Put simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As a web app user, I have a preference. At night, I prefer all my apps to be on dark mode. Sometimes during the day, I place all apps on dark mode, especially my Twitter app. I believe every other user also has a preference so giving users the ability to set your app theme the way they like is a big win for User Experience (UX) - TheReactNewbie&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hope you agree with me 😉&lt;/p&gt;

&lt;p&gt;Now for the how?&lt;/p&gt;

&lt;h3&gt;
  
  
  How can you add a switch between light and dark mode in your React App?
&lt;/h3&gt;

&lt;p&gt;TailwindCSS makes this very easy.&lt;/p&gt;

&lt;p&gt;Fortunately for me and for you, I have already written a step-by-step guide on how to do this so&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thereactnewbie.xyz/light-to-dark-mode-theme-3-easy-steps-to-do-it-in-your-reactjs-app-using-tailwindcss"&gt;Head over to the article here and enjoy!&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Okay. That's it for now.&lt;/p&gt;

&lt;p&gt;I hope you found this article helpful.&lt;/p&gt;

&lt;p&gt;I welcome feedback and constructive criticisms of my portfolio. Thank you as you do&lt;/p&gt;

&lt;p&gt;Here's a link to the portfolio again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.georgeisiguzo.xyz/"&gt;https://www.georgeisiguzo.xyz/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>How to build a Modal Component with Vite, React Custom Hooks and TailwindCSS</title>
      <dc:creator>Georgie</dc:creator>
      <pubDate>Tue, 28 Jun 2022 20:46:00 +0000</pubDate>
      <link>https://dev.to/georgeisiguzo/how-to-build-a-modal-component-with-vite-react-custom-hooks-and-tailwindcss-55a2</link>
      <guid>https://dev.to/georgeisiguzo/how-to-build-a-modal-component-with-vite-react-custom-hooks-and-tailwindcss-55a2</guid>
      <description>&lt;p&gt;Hello Friend👋&lt;/p&gt;

&lt;p&gt;Let's do some coding practice together by building a modal component.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Full disclosure: I'm still learning ReactJs and Vite and TailwindCSS and many more things. Lol... &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What You'll Learn
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;How to create a React app with Vite&lt;/li&gt;
&lt;li&gt;How to statically position an element relative to a browser window using TailwindCSS&lt;/li&gt;
&lt;li&gt;How to create a custom hook&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What We Will Build
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sYrIT5ni--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mrsr0gkdk5lz68oyd5g4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sYrIT5ni--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mrsr0gkdk5lz68oyd5g4.gif" alt="Modal Component" width="484" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Excited? Let's begin!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Setup
&lt;/h2&gt;

&lt;p&gt;There's been a lot of buzzes lately about creating ReactJs apps with Vite so let's give that a try shall we?&lt;/p&gt;

&lt;p&gt;First, we create a Vite project with the command below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you'll be asked to name your project like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PrEF69n1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpg0yr16rvpkc21kceci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PrEF69n1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpg0yr16rvpkc21kceci.png" alt="demo.png" width="426" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, select the framework for this tutorial like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ocwpyWe4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/919owmpsov6xbov9dgec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ocwpyWe4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/919owmpsov6xbov9dgec.png" alt="demo1.png" width="450" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's all the setup you need for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Start the server
&lt;/h2&gt;

&lt;p&gt;Now we will install the dependencies we need and start the server using the commands below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install &amp;amp;&amp;amp; npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you open up your browser and enter the address: &lt;code&gt;http://localhost:3000/&lt;/code&gt; you should see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J5FE4Sgo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tikpoznqrkwf91q2vun8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J5FE4Sgo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tikpoznqrkwf91q2vun8.gif" alt="vite app.gif" width="595" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If this is your first time creating a React app with Vite then &lt;strong&gt;congrats!&lt;/strong&gt; (It's my first time too 😁)&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Add TailwindCSS to your project
&lt;/h2&gt;

&lt;p&gt;We will use TailwindCSS to style our app so let's add it to our project with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D tailwindcss postcss autoprefixer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and another command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx tailwindcss init -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create two new files, &lt;code&gt;postcss.config.js&lt;/code&gt; &amp;amp; &lt;code&gt;tailwind.config.js&lt;/code&gt;, in the root directory of our project.&lt;/p&gt;

&lt;p&gt;Now on the &lt;code&gt;tailwind.config.js&lt;/code&gt; file, remove all the code in it and replace it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{js,jsx,ts,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then finally in this step, locate your &lt;code&gt;index.css&lt;/code&gt; file in the root directory, delete all the codes in it and add these 3 lines of code at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By now your root directory should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0OOfe84C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/twsqs13f61tlkybswibi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0OOfe84C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/twsqs13f61tlkybswibi.png" alt="root.png" width="277" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and your &lt;code&gt;index.css&lt;/code&gt; should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rqD55_uB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qrxv6guboesufe7qll6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rqD55_uB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qrxv6guboesufe7qll6p.png" alt="index css file.png" width="511" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's check if we've properly added TailwindCSS to our project.&lt;/p&gt;

&lt;p&gt;Stop your server and restart it with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now go to &lt;code&gt;http://localhost:3000/&lt;/code&gt; and this is what your app will look like now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IL7-JTtg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/583g3p326wzj2hd56zo5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IL7-JTtg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/583g3p326wzj2hd56zo5.gif" alt="vite app with tailwind.gif" width="595" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice any changes?&lt;/p&gt;

&lt;p&gt;Yes, the style on the button: &lt;strong&gt;"count is: 0"&lt;/strong&gt; and on the links &lt;strong&gt;"Learn React | Vite Docs"&lt;/strong&gt; has changed.&lt;/p&gt;

&lt;p&gt;This shows that Tailwind has been added successfully. If you don't notice any change on yours, please refer back to the instructions above and try to find out what you didn't do correctly.&lt;/p&gt;

&lt;p&gt;To read more about Vite please refer to this article by &lt;a href="https://lo-victoria.com/introduction-to-vite-the-next-generation-frontend-tooling#heading-step-1-create-vite-project"&gt;Victoria Lo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also use &lt;a href="https://tailwindcss.com/docs/guides/create-react-app"&gt;TailwindCSS official doc&lt;/a&gt; to learn how to add Tailwind to a React app&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3:  Getting our hands dirty
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;Components&lt;/code&gt; folder inside the &lt;code&gt;src&lt;/code&gt; directory and then create a file &lt;code&gt;Navbar.jsx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your folder structure should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jtp13Dvs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jiivyigrj4jztbwpov51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jtp13Dvs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jiivyigrj4jztbwpov51.png" alt="folder.png" width="283" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now open the &lt;code&gt;Navbar.jsx&lt;/code&gt; file and paste the code below into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

export default function Navbar() {
  return (
    &amp;lt;nav className="flex items-center justify-between flex-wrap bg-teal-500 p-4"&amp;gt;
      &amp;lt;div className="flex items-center flex-shrink-0 text-white mr-6"&amp;gt;
        &amp;lt;svg
          className="fill-current h-8 w-8 mr-2"
          width="54"
          height="54"
          viewBox="0 0 54 54"
          xmlns="http://www.w3.org/2000/svg"
        &amp;gt;
          &amp;lt;path d="M13.5 22.1c1.8-7.2 6.3-10.8 13.5-10.8 10.8 0 12.15 8.1 17.55 9.45 3.6.9 6.75-.45 9.45-4.05-1.8 7.2-6.3 10.8-13.5 10.8-10.8 0-12.15-8.1-17.55-9.45-3.6-.9-6.75.45-9.45 4.05zM0 38.3c1.8-7.2 6.3-10.8 13.5-10.8 10.8 0 12.15 8.1 17.55 9.45 3.6.9 6.75-.45 9.45-4.05-1.8 7.2-6.3 10.8-13.5 10.8-10.8 0-12.15-8.1-17.55-9.45-3.6-.9-6.75.45-9.45 4.05z" /&amp;gt;
        &amp;lt;/svg&amp;gt;
        &amp;lt;span className="font-semibold text-xl tracking-tight"&amp;gt;
          Tailwind Shop
        &amp;lt;/span&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div className="block"&amp;gt;
        {/** lg:hidden */}
        &amp;lt;button className="flex items-center px-3 py-2 border rounded text-teal-200 border-teal-400 hover:text-white hover:border-white"&amp;gt;
          &amp;lt;svg
            className="fill-current h-3 w-3"
            viewBox="0 0 20 20"
            xmlns="http://www.w3.org/2000/svg"
          &amp;gt;
            &amp;lt;title&amp;gt;Menu&amp;lt;/title&amp;gt;
            &amp;lt;path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" /&amp;gt;
          &amp;lt;/svg&amp;gt;
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/nav&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now find the &lt;code&gt;App.jsx&lt;/code&gt; file, delete all the codes in it and paste the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import Navbar from "./Components/Navbar";

export default function App() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Navbar /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Just in case this is your first time using TailwindCSS...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the &lt;code&gt;Navbar.jsx&lt;/code&gt; file, you must have noticed some codes like this: &lt;code&gt;className="font-semibold text-xl tracking-tight"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is how we use TailwindCSS in our code. Tailwind has classes that when added to the &lt;code&gt;className&lt;/code&gt; attribute of an element, it changes the styling of that element. &lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;font-semibold&lt;/code&gt; will change the font-weight of an element to &lt;code&gt;font-weight: 600;&lt;/code&gt; in vanilla CSS.&lt;/p&gt;

&lt;p&gt;In our use case, we added &lt;code&gt;font-semibold&lt;/code&gt; to the &lt;code&gt;span&lt;/code&gt; element that holds &lt;code&gt;Tailwind Shop&lt;/code&gt; text in the navbar. Try changing &lt;code&gt;font-semibold&lt;/code&gt; to &lt;code&gt;font-extrabold&lt;/code&gt; and notice the difference.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use of empty tags: &lt;code&gt;&amp;lt;&amp;gt;&amp;lt;/&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the &lt;code&gt;App.jsx&lt;/code&gt; file, we placed the &lt;code&gt;Navbar&lt;/code&gt; component in an empty tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;&amp;gt;
      &amp;lt;Navbar /&amp;gt;
&amp;lt;/&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this is your first time seeing an &lt;strong&gt;empty tag&lt;/strong&gt;, don't worry, it won't give an error. You can read about it &lt;a href="https://thereactnewbie.xyz/some-big-terms-in-reactjs-what-are-elements-components-and-fragments"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go back to our app on the browser and notice the changes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BIAtg8E9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eauk35qclilmen060uqe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BIAtg8E9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eauk35qclilmen060uqe.png" alt="added navbar.png" width="615" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good, we are getting there.&lt;/p&gt;

&lt;p&gt;We are creating something that looks like an e-commerce web app (because e-commerce web apps love using modals 😁)&lt;/p&gt;

&lt;h4&gt;
  
  
  Now let's create a product card that a user can click on.
&lt;/h4&gt;

&lt;p&gt;Inside the &lt;code&gt;Components&lt;/code&gt; folder, create a &lt;code&gt;Product.jsx&lt;/code&gt; file and paste this code to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

export default function Product(props) {
  return (
    &amp;lt;div className="max-w-xs rounded overflow-hidden shadow-lg my-4"&amp;gt;
      &amp;lt;img
        className="w-full"
        src="https://cdn.shopify.com/s/files/1/1626/8507/products/classic-dad-hat-pink-front-620a928e93e58_345x550.jpg?v=1644860054"
        alt="Sunset in the mountains"
      /&amp;gt;
      &amp;lt;div className="flex justify-between px-6 py-4"&amp;gt;
        &amp;lt;div className="font-bold text-xl"&amp;gt;The Coldest Sunset&amp;lt;/div&amp;gt;
        &amp;lt;div className="font-bold font-mono text-xl text-red-700"&amp;gt;$35&amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's import it into our &lt;code&gt;App.jsx&lt;/code&gt; component 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;import React from "react";
import Navbar from "./Components/Navbar";
import Product from "./Components/Product"; // just added

export default function App() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Navbar /&amp;gt;
      {/* just added */}
      &amp;lt;div className="flex justify-center"&amp;gt;
        &amp;lt;Product /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our web app should look like this now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G808NKdo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mky46v0y7qvgw8m735sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G808NKdo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mky46v0y7qvgw8m735sd.png" alt="added product.png" width="338" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Creating our modal component
&lt;/h2&gt;

&lt;p&gt;Create a new file in &lt;code&gt;Components&lt;/code&gt; directory (or folder) with the name &lt;code&gt;Modal.jsx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Paste this code into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

export default function Modal(props) {
  return (
    &amp;lt;div className="static"&amp;gt;
      &amp;lt;div className="fixed h-screen w-screen bg-black z-10 top-0 opacity-75"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now import the modal into &lt;code&gt;App.jsx&lt;/code&gt; component as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import Navbar from "./Components/Navbar";
import Product from "./Components/Product";
import Modal from "./Components/Modal"; // just added

export default function App() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Navbar /&amp;gt;
      &amp;lt;div className="flex justify-center"&amp;gt;
        &amp;lt;Product /&amp;gt;
      &amp;lt;/div&amp;gt;
      {/* just added */}
      &amp;lt;Modal /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see this on our web page now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C8gkF8IU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96gz70pmzwvna9g0oglt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C8gkF8IU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96gz70pmzwvna9g0oglt.png" alt="added opacity.png" width="333" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice any change? &lt;/p&gt;

&lt;p&gt;Our page has suddenly become dark. Why? Where is the modal?&lt;/p&gt;

&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;We are not done yet&lt;/li&gt;
&lt;li&gt;Before adding the actual content of the modal, we added an element that will cover the entire screen whenever our modal is on display.&lt;/li&gt;
&lt;li&gt;This element has a dark opacity (&lt;code&gt;opacity-75&lt;/code&gt;) that's why our web page looks dark currently&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notice that the parent element in the modal component has &lt;code&gt;static&lt;/code&gt; added to the &lt;code&gt;className&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;&amp;lt;div className="static"&amp;gt; ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the element that covers the entire screen has &lt;code&gt;fixed&lt;/code&gt; added to its &lt;code&gt;className&lt;/code&gt; attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className="fixed h-screen w-screen bg-black z-10 top-0 opacity-75"&amp;gt;...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple way to position an element relative to the browser window using TailwindCSS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two things to note:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The direct parent of the element you want to position should have a &lt;code&gt;static&lt;/code&gt; class added to it&lt;/li&gt;
&lt;li&gt;While the element you want to position will have a &lt;code&gt;fixed&lt;/code&gt; class added to it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Easy right?&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://tailwindcss.com/docs/position#statically-positioning-elements"&gt;Tailwind docs&lt;/a&gt; for positioning elements to learn more.&lt;/p&gt;

&lt;h4&gt;
  
  
  Now let's add the modal content
&lt;/h4&gt;

&lt;p&gt;Edit &lt;code&gt;Modal.jsx&lt;/code&gt; component 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;import React from "react";

export default function Modal(props) {
  return (
    &amp;lt;div className="static"&amp;gt;
      &amp;lt;div
        className="fixed h-screen w-screen bg-black z-10 top-0 opacity-75"
      &amp;gt;&amp;lt;/div&amp;gt;
      { /** Just added */}
      &amp;lt;div className="fixed top-0 right-0 left-0 z-20 flex justify-center"&amp;gt;
        &amp;lt;div className="mx-4 my-4 bg-white"&amp;gt;
            &amp;lt;div className="flex justify-end"&amp;gt;
                &amp;lt;button 
                    className="border-2 text-red-900 px-2 m-2"
                &amp;gt;
                    X
                &amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div className=" bg-white"&amp;gt;
                &amp;lt;img
                    className="w-full"
                    src="https://cdn.shopify.com/s/files/1/1626/8507/products/classic-dad-hat-pink-front-620a928e93e58_345x550.jpg?v=1644860054"
                    alt="Sunset in the mountains"
                /&amp;gt;
                &amp;lt;div className="flex justify-between px-6 py-1"&amp;gt;
                    &amp;lt;div className="font-bold text-xl"&amp;gt;The Coldest Sunset&amp;lt;/div&amp;gt;
                    &amp;lt;div className="font-bold font-mono text-xl text-red-700"&amp;gt;$35&amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div className="flex justify-around items-center px-2 py-1"&amp;gt;
                    &amp;lt;button className="border-2 px-2"&amp;gt;-&amp;lt;/button&amp;gt;
                    &amp;lt;div className="font-bold font-mono text-xl text-red-700"&amp;gt;Quanity: 1&amp;lt;/div&amp;gt;
                    &amp;lt;button className="border-2 px-2"&amp;gt;+&amp;lt;/button&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div className="flex justify-around items-center px-2 py-1"&amp;gt;
                    &amp;lt;button className="border-2 px-2 py-1 rounded bg-green-500 text-white font-bold font-mono text-lg"&amp;gt;Add to Cart&amp;lt;/button&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the web app:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fq0wXSLJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2ykh95ts9mrb8fksacv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fq0wXSLJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2ykh95ts9mrb8fksacv.png" alt="added modal content.png" width="324" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! Our modal is showing!&lt;/p&gt;

&lt;p&gt;Now we will need to add logic so that our modal only shows up when we want to view it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Adding logic to our modal using Custom Hooks
&lt;/h2&gt;

&lt;p&gt;The fun part is here. Let's take it slowly now.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new folder for our custom hooks. Name the folder Hooks&lt;/li&gt;
&lt;li&gt;Inside the Hooks folder (directory), create a new file with the name &lt;code&gt;useToggle.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Note: it's &lt;code&gt;useToggle.js&lt;/code&gt; and not &lt;code&gt;useToggle.jsx&lt;/code&gt;. This is because there will be no &lt;code&gt;jsx&lt;/code&gt; code in this file (script).&lt;/li&gt;
&lt;li&gt;Copy and paste the command below into &lt;code&gt;useToggle.js&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";

export default function useToggle() {
  const [on, setOn] = useState(false);

  const toggler = () =&amp;gt; {
    setOn((on) =&amp;gt; !on);
  };

  return { on, toggler };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;We imported &lt;code&gt;useState&lt;/code&gt;, a hook that comes with React that allows us to save data in state inside a function component.&lt;/li&gt;
&lt;li&gt;What we are saving in state:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [on, setOn] = useState(false);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are saving a boolean named &lt;code&gt;on&lt;/code&gt; and right next to it is &lt;code&gt;setOn&lt;/code&gt; a function that lets you update the value of &lt;code&gt;on&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We then create &lt;code&gt;toggler&lt;/code&gt;, an arrow function that will call &lt;code&gt;setOn&lt;/code&gt; to update the value of &lt;code&gt;on&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Lastly, we return &lt;code&gt;on&lt;/code&gt; and &lt;code&gt;toggler&lt;/code&gt; inside an object wrapping them in curly braces (&lt;code&gt;{}&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now let's use &lt;code&gt;useToggle&lt;/code&gt; in our &lt;code&gt;App&lt;/code&gt;, &lt;code&gt;Product&lt;/code&gt; and &lt;code&gt;Modal&lt;/code&gt; components.&lt;/p&gt;

&lt;p&gt;In App.js, import &lt;code&gt;useToggle.js&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;import useToggle from "./Hooks/useToggle";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The retrieve (or destructure) &lt;code&gt;on&lt;/code&gt; and &lt;code&gt;toggler&lt;/code&gt; from &lt;code&gt;useToggle&lt;/code&gt; like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { on, toggler } = useToggle();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's use the value of &lt;code&gt;on&lt;/code&gt; to conditionally show &lt;code&gt;Modal&lt;/code&gt; 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;{on &amp;amp;&amp;amp; &amp;lt;Modal toggler={toggler} /&amp;gt; /** just added */}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What the above code means is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-&amp;gt; whenever on is true, render (or display) the &amp;lt;Modal /&amp;gt; component
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the code in &lt;code&gt;App.jsx&lt;/code&gt; should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import Navbar from "./Components/Navbar";
import Product from "./Components/Product";
import Modal from "./Components/Modal";
import useToggle from "./Hooks/useToggle"; // just added

export default function App() {
  const { on, toggler } = useToggle(); // just added

  return (
    &amp;lt;&amp;gt;
      &amp;lt;Navbar /&amp;gt;
      &amp;lt;div className="flex justify-center"&amp;gt;
        &amp;lt;Product toggler={toggler} /&amp;gt;
      &amp;lt;/div&amp;gt;
      {on &amp;amp;&amp;amp; &amp;lt;Modal toggler={toggler} /&amp;gt; /** just added */}
    &amp;lt;/&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Modal will only show when &lt;code&gt;on&lt;/code&gt; is true.&lt;/p&gt;

&lt;p&gt;View your web app, notice now that the modal has disappeared?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--25RGVpUl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cg8caqas2vvu1cgncfas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--25RGVpUl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cg8caqas2vvu1cgncfas.png" alt="added product.png" width="338" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But how will we bring it back to the page when we need it?&lt;/p&gt;

&lt;p&gt;We pass toggler as a prop to both the &lt;code&gt;Product&lt;/code&gt; component and the &lt;code&gt;Modal&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Product toggler={toggler} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Modal toggler={toggler} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now on &lt;code&gt;Product.jsx&lt;/code&gt; add an onClick event so that will call &lt;code&gt;toggler&lt;/code&gt; whenever the product component is clicked on:&lt;/p&gt;

&lt;p&gt;Do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

export default function Product(props) {
  return (
    &amp;lt;div 
        onClick={() =&amp;gt; props.toggler()} // just added
        className="max-w-xs rounded overflow-hidden shadow-lg my-4"
    &amp;gt;
// the rest of the code should be the same
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in &lt;code&gt;Modal.jsx&lt;/code&gt;, add an onClick event to the &lt;code&gt;X&lt;/code&gt; button so that it calls &lt;code&gt;toggler&lt;/code&gt; whenever it is clicked on. &lt;/p&gt;

&lt;p&gt;Do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

export default function Modal(props) {
  return (
    &amp;lt;div className="static"&amp;gt;
      &amp;lt;div className="fixed h-screen w-screen bg-black z-10 top-0 opacity-75"&amp;gt;&amp;lt;/div&amp;gt;
      {/** Just added */}
      &amp;lt;div className="fixed top-0 right-0 left-0 z-20 flex justify-center"&amp;gt;
        &amp;lt;div className="mx-4 my-4 bg-white"&amp;gt;
          &amp;lt;div className="flex justify-end"&amp;gt;
            &amp;lt;button
              onClick={() =&amp;gt; props.toggler()}
              className="border-2 text-red-900 px-2 m-2"
            &amp;gt;
              X
            &amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
// the rest of the code should be the same
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to save all the files we just edited.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: View the App
&lt;/h2&gt;

&lt;p&gt;We are done!&lt;/p&gt;

&lt;p&gt;Head back to the browser and see the magic unfold:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B-Sac2cK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovp3gypl607enslx3onm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B-Sac2cK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovp3gypl607enslx3onm.gif" alt="app done.gif" width="685" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice isn't it?&lt;/p&gt;

&lt;p&gt;Congrats! We've successfully built a working modal component in an e-commerce app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read More:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/hooks-overview.html"&gt;React Hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hashnode.com/authenticate?next=https://blog.connectwithmusa.com/how-to-create-a-new-react-project-using-vite-with-tailwindcss"&gt;Vite + React + TailwindCSS by Musa Ahmed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simplecoder.hashnode.dev/how-to-write-our-own-custom-hooks-in-react"&gt;Custom Hooks by Simple Coder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medusa.hashnode.dev/introdution-to-usestate-hooks-in-react-1"&gt;useState Hooks by Medusa's blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lo-victoria.com/series/a-look-at-react-hooks"&gt;This whole series on React Hooks by Victoria Lo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I'll be using this modal example to also explain React Context API and the difference between Context API and Custom Hooks.&lt;/p&gt;

&lt;p&gt;Do keep in touch. See ya ✌️&lt;/p&gt;

</description>
      <category>react</category>
      <category>tailwindcss</category>
      <category>codenewbie</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Dev x Appwrite Hackathon: #5 Getting Started on DevSpace Forum</title>
      <dc:creator>Georgie</dc:creator>
      <pubDate>Mon, 09 May 2022 21:38:45 +0000</pubDate>
      <link>https://dev.to/georgeisiguzo/dev-x-appwrite-hackathon-5-getting-started-on-devspace-forum-1n7i</link>
      <guid>https://dev.to/georgeisiguzo/dev-x-appwrite-hackathon-5-getting-started-on-devspace-forum-1n7i</guid>
      <description>&lt;p&gt;Greetings from this side 😊&lt;/p&gt;

&lt;p&gt;This is the final article of this series. I will briefly write about how to get started on DevSpace Forum (&lt;em&gt;The app I created during the Hackathon&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;I will also talk about future plans and features for the app.&lt;/p&gt;

&lt;p&gt;But firstly, the app details.&lt;/p&gt;

&lt;h2&gt;
  
  
  DevSpace Forum
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;App URL - &lt;a href="https://devspace-forum.netlify.app/"&gt;https://devspace-forum.netlify.app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;App Screenshot &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Welcome/Onboarding page&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QmHT2o8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xxdpdk99ccdnmavq5ksu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QmHT2o8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xxdpdk99ccdnmavq5ksu.png" alt="DevSpace Forum Welcome page" width="788" height="683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Home Page&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PkvN3_Ww--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqkwhsmpkl0v0g1h1ext.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PkvN3_Ww--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqkwhsmpkl0v0g1h1ext.png" alt="DevSpace Forum HomePage" width="704" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Space Page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5v0xt3S7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zuo16vmuctt1o8f4ezcr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5v0xt3S7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zuo16vmuctt1o8f4ezcr.png" alt="Devspace forum new space page" width="714" height="669"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ask A Question Page&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vediH05f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i45eqa20hb06upd23eey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vediH05f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i45eqa20hb06upd23eey.png" alt="Devspace forum new question page" width="813" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Navigate through Spaces/Questions&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kX8a8nu7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek638ib3ws7aemyz5iju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kX8a8nu7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek638ib3ws7aemyz5iju.png" alt="Devspace forum navigation" width="679" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Profile Page&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QI1f1JAy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92hewe6naudkd2jf7phb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QI1f1JAy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92hewe6naudkd2jf7phb.png" alt="Devspace forum user profile" width="727" height="662"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;On the onboarding page, you can sign up with your email. You will need to fill in the username and password fields.&lt;/p&gt;

&lt;p&gt;Alternatively, you can log in with google by clicking on the google icon below the form.&lt;/p&gt;

&lt;p&gt;Once you're signed in, you can create a space, ask a question, or find an existing space to join (live or upcoming)&lt;/p&gt;

&lt;p&gt;Find the link to a space by clicking on the space.&lt;/p&gt;

&lt;p&gt;At the moment, a space can be held via zoom or google meet.&lt;/p&gt;

&lt;p&gt;The whole essence of Devspace is to allow programmers to ask and explain concepts and technologies during live video sessions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Future features
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. In-App Video Session:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of using Google Meet or Zoom for live sessions, an in-app video session feature will be developed.&lt;/p&gt;

&lt;p&gt;This will keep all activities within the app and to better regulate them&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. In-App Chat:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An In-App chat feature should bring everyone closer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Improve User Interface/ User Experience:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is just version 1.0 😉&lt;/p&gt;

&lt;p&gt;Hopefully, the subsequent versions should look and feel better.&lt;/p&gt;

&lt;p&gt;At the moment, users cannot edit their profile via the profile page.&lt;/p&gt;

&lt;p&gt;With limited time on my hands at present, I will be working on it as soon as I get the chance to.&lt;/p&gt;
&lt;h2&gt;
  
  
  Source Code / Repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Mr-Georgie"&gt;
        Mr-Georgie
      &lt;/a&gt; / &lt;a href="https://github.com/Mr-Georgie/Dev-Space-Forum"&gt;
        Dev-Space-Forum
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      DevSpace Forum is an online community where you can get your tech related questions answered via video conferencing. You can also talk about the latest technology you're using in live sessions.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
DevSpace Forum · &lt;a href="https://www.npmjs.com/package/react" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/98ed63c9884d96bf0477b9f54f1a71a6bba3cb7bf39fe6d4a87805b11d9743ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e706d2d76362e31342e31332d626c7565" alt="npm version"&gt;&lt;/a&gt; &lt;a href="https://github.com/facebook/react/blob/main/LICENSE"&gt;&lt;img src="https://camo.githubusercontent.com/cdd1e7448caec22a3564b58ee80179eaeb5efb6a149cc268a7e3d15b9f05f52d/68747470733a2f2f696d672e736869656c64732e696f2f686578706d2f6c2f617061" alt="GitHub license"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;DevSpace Forum is an online community where you can get your tech related questions answered via video conferencing. You can also talk about the latest technology you're using in live sessions.&lt;/p&gt;
&lt;p&gt;Questions on DevSpace can be in the form of "how to's", "getting started", "introduction", "onboarding experience", etc.&lt;/p&gt;
&lt;h2&gt;
Preview&lt;/h2&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://user-images.githubusercontent.com/28518667/167266369-9cd83538-8441-4750-891b-477aa960dd17.gif"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ChcbSQXA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/28518667/167266369-9cd83538-8441-4750-891b-477aa960dd17.gif" alt="devspace"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Description&lt;/h2&gt;
&lt;p&gt;The DevSpace Forum will be made with the following technologies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React &amp;amp; React-Router (FrontEnd)&lt;/li&gt;
&lt;li&gt;TailWind CSS&lt;/li&gt;
&lt;li&gt;AppWrite (API, Authentication &amp;amp; Database)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;p&gt;In the project directory, you can run:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm start&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This will install all the dependencies from the package.json file&lt;/p&gt;
&lt;h2&gt;
Contributing&lt;/h2&gt;
&lt;p&gt;DevSpace Forum is open sourced so it can be used by others. See the LICENSE file for terms and conditions&lt;/p&gt;
&lt;p&gt;Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
&lt;h2&gt;
License&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.apache.org/licenses/LICENSE-2.0" rel="nofollow"&gt;Apache-2 permissive license&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Mr-Georgie/Dev-Space-Forum"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Take-aways
&lt;/h2&gt;

&lt;p&gt;Wow, I must say I've learned a lot during this time.&lt;/p&gt;

&lt;p&gt;I used &lt;a href="https://reactjs.org/docs/render-props.html"&gt;React Render Props&lt;/a&gt; and then I changed to &lt;a href="https://reactjs.org/docs/context.html"&gt;React Context&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I felt &lt;a href="https://reactjs.org/docs/context.html"&gt;React Context&lt;/a&gt; was better in this use case.&lt;/p&gt;

&lt;p&gt;Tailwind CSS! I'm adding that to my CV/Portfolio Asap! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Operation get a tech job is in motion! 😁😂&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hmmm... How about working on a limited time frame. Phew... For someone who has a 9-5 Mondays - Fridays, I really pushed myself.&lt;/p&gt;

&lt;p&gt;This is my first encounter with droplets, containers, nano (Linux terminal editor), Gitpod, Digital Ocean, and Appwrite!&lt;/p&gt;

&lt;p&gt;Kudos to the Appwrite team for the easy-to-read documentation, and the growing Appwrite community that supports you when you hit a brick wall (bugs 😪).&lt;/p&gt;

&lt;p&gt;Speaking about the Appwrite community, I feel like writing blog articles and tutorials that will be of help to newbies in the community like myself.&lt;/p&gt;

&lt;p&gt;We'll see how that goes.&lt;/p&gt;

&lt;p&gt;Finally, kudos to the &lt;strong&gt;DEV Community&lt;/strong&gt; for this cool platform to write articles on the go with my phone whenever I'm less busy 😉&lt;/p&gt;

&lt;p&gt;That's all for now.&lt;/p&gt;

&lt;p&gt;See you later—ciao!&lt;/p&gt;

</description>
      <category>appwritehack</category>
      <category>javascript</category>
      <category>react</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Dev x Appwrite Hackathon: #4 Installing Appwrite on Digital Ocean</title>
      <dc:creator>Georgie</dc:creator>
      <pubDate>Sat, 07 May 2022 17:16:42 +0000</pubDate>
      <link>https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-4-installing-appwrite-on-digital-ocean-30hi</link>
      <guid>https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-4-installing-appwrite-on-digital-ocean-30hi</guid>
      <description>&lt;p&gt;Hi friends!&lt;/p&gt;

&lt;p&gt;Some days back, I installed Appwrite on Digital Ocean and it was pretty easy.&lt;/p&gt;

&lt;p&gt;I didn't do it without any help though. I found several tutorials that helped.&lt;/p&gt;

&lt;p&gt;So this is me giving back to the appwrite community and hopefully, this will help another appwrite newbie (I'm basically a Digital Ocean newbie too 😂)&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Go to Appwrite Docs
&lt;/h2&gt;

&lt;p&gt;Go to &lt;a href="https://appwrite.io/docs/installation#one-click-setups"&gt;Appwrite Installation Docs -&amp;gt; One Click Setups&lt;/a&gt;, then click on "Click to install" as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NflP0ebg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nutbal2kccfunbl1tank.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NflP0ebg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nutbal2kccfunbl1tank.png" alt="Appwrite one-click install page" width="642" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will take you to digital oceans marketplace. Then click on "Create droplet" as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9G9eqHFF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egg8x8o0ngt9j4xnebep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9G9eqHFF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egg8x8o0ngt9j4xnebep.png" alt="Digital ocean install appwrite" width="880" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have an account on digital ocean, and you've added a payment method, you should be looking at a form now.&lt;/p&gt;

&lt;p&gt;Let's fill out the form.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Digital ocean gives $100 free credit to new users once you add a payment method i.e your credit/debit card&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2: Filling out the form
&lt;/h2&gt;

&lt;p&gt;Use the screenshots below to fill the form accordingly:&lt;/p&gt;

&lt;p&gt;This...&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8iwhl5vC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4b8oyrj1iaxcicoih4d3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8iwhl5vC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4b8oyrj1iaxcicoih4d3.png" alt="install appwrite 1" width="866" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This...&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0wmNj8w6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4i7sm2defdwinot1rmpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0wmNj8w6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4i7sm2defdwinot1rmpo.png" alt="install appwrite 2" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This...&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hb1YGJm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zcw4so31jye18q0vq638.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hb1YGJm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zcw4so31jye18q0vq638.png" alt="install appwrite 3" width="880" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally this...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8GsaGOTZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k19vdthfku14aba0yudj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8GsaGOTZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k19vdthfku14aba0yudj.png" alt="install appwrite 4" width="871" height="527"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Configuration
&lt;/h2&gt;

&lt;p&gt;Get your Appwrite droplet endpoint (IP address) from your digital ocean dashboard here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MGcPRFv_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9tmhdr0gfb6eq7lttle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MGcPRFv_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9tmhdr0gfb6eq7lttle.png" alt="appwrite IP address on digitalocean" width="880" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Paste the IP address on a new tab and sign up.&lt;/p&gt;

&lt;p&gt;Now you can go ahead to set up your Appwrite backend using Appwrite docs &lt;a href="https://appwrite.io/docs/getting-started-for-web"&gt;here&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;That's if you don't know how to setup appwrite&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  SMTP Disabled Warning
&lt;/h2&gt;

&lt;p&gt;Now if you've gotten to the point where you want to create an account from your frontend app using appwrite SDK:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;appwrite.account.create('unique()', 'me@example.com', 'password', 'Jane Doe')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You'll get a warning on your console saying:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SMTP Disabled&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means that your Appwrite server was not able to send a verification email to the email address you passed to &lt;code&gt;.account.create(..)&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Enable SMTP from Digital Ocean console
&lt;/h2&gt;

&lt;p&gt;This was where I was stuck a little because normally, to enable SMTP, I just need to add SMTP details to my appwrite &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;But where can I find my appwrite files on digital ocean?&lt;/p&gt;

&lt;p&gt;I wondered 🤔&lt;/p&gt;

&lt;p&gt;After some google searching, one tutorial I found (which I will mention at the end) directed me to my appwrite droplet console.&lt;/p&gt;

&lt;p&gt;Access your appwrite droplet console here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RhsU6gLo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/61ay13lwbwajacrlq3gf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RhsU6gLo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/61ay13lwbwajacrlq3gf.png" alt="find appwrite droplet console" width="880" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click on "Launch Console"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZFYaqNAZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bg5puz3x1dzu5i9o7quz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZFYaqNAZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bg5puz3x1dzu5i9o7quz.png" alt="launch console" width="880" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the console is launched, you should see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CLsBTShM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykoa169myknysjyo9qlj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CLsBTShM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykoa169myknysjyo9qlj.png" alt="appwrite droplet console" width="550" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now right where the arrow in the screenshot above is pointing, type the command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd appwrite&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Press enter then type this too:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nano .env&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Press enter as well.&lt;/p&gt;

&lt;p&gt;Now your &lt;code&gt;.env&lt;/code&gt; file should be opened.&lt;/p&gt;

&lt;p&gt;Move the cursor to the line &lt;code&gt;_APP_SMTP_HOST&lt;/code&gt; as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HsxRLYsx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/95ozt8okgft7p1rgz8a9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HsxRLYsx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/95ozt8okgft7p1rgz8a9.png" alt="edit appwrite .env file" width="359" height="127"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And edit all the lines below with your own SMTP settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_APP_SMTP_HOST=smtp.mailgun.org
_APP_SMTP_PORT=587
_APP_SMTP_SECURE=tls
_APP_SMTP_USERNAME=YOUR-SMTP-USERNAME
_APP_SMTP_PASSWORD=YOUR-SMTP-PASSWORD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;I use mailgun free account for testing purposes. You can create one too by clicking &lt;a href="https://login.mailgun.com/login/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now when you're done, press &lt;code&gt;control + o&lt;/code&gt; to save the file.&lt;/p&gt;

&lt;p&gt;This will appear at the bottom of your screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dH3MyLBR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8btx9chelwz2ckcetks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dH3MyLBR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8btx9chelwz2ckcetks.png" alt="save .env file" width="502" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press enter then you can either close the windows or press `Control + X to close the console.&lt;/p&gt;

&lt;p&gt;Almost done.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 5: Rebuild your Appwrite stack
&lt;/h2&gt;

&lt;p&gt;Normally, you should restart your appwrite server to see if everything is working fine...&lt;/p&gt;

&lt;p&gt;but in other not to waste time going back and forth with it, One sure-fire way to make sure your changes in &lt;code&gt;.env&lt;/code&gt; have taken effect is to rebuild your Appwrite stack.&lt;/p&gt;

&lt;p&gt;Launch the console again (remember you can launch the console from your digital ocean dashboard)&lt;/p&gt;

&lt;p&gt;Once the console is up, type and press enter the following command:&lt;/p&gt;

&lt;p&gt;this&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;cd appwrite&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and then this&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
docker-compose up -d --build --force-recreate&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
It should rebuild and restart your appwrite server.&lt;/p&gt;

&lt;p&gt;Head back to your front end and try to create an account again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can also test SMTP from your Appwrite Console by logging out and clicking on 'forget password' to see if you'll receive a mail to create a new password.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And we are done!... Phew...&lt;/p&gt;

&lt;p&gt;Wasn't difficult, was it?&lt;/p&gt;
&lt;h2&gt;
  
  
  Update on the DevSpace Forum App
&lt;/h2&gt;

&lt;p&gt;I'm 90% done!&lt;/p&gt;

&lt;p&gt;View the app live &lt;a href="https://devspace-forum.netlify.app/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can sign in (with google too)&lt;/p&gt;

&lt;p&gt;Create a space... Ask a question... Test it out.&lt;/p&gt;

&lt;p&gt;What's left to do?&lt;/p&gt;

&lt;p&gt;I want to use Appwrite Storage Services to allow users add profile pictures and cover images for a space.&lt;/p&gt;

&lt;p&gt;Hmmm... I wish I had more free time.&lt;/p&gt;

&lt;p&gt;My last post in this series will be on how to use Devspace Forum.&lt;/p&gt;

&lt;p&gt;See ya then!&lt;/p&gt;
&lt;h2&gt;
  
  
  Useful resources I used for this article:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs/email-delivery"&gt;Appwrite Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.r-bloggers.com/2021/10/setting-up-appwrite-on-digitalocean/"&gt;Setting Up Appwrite on Digital Ocean by Joshua Cook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/appwrite/30daysofappwrite-appwrite-for-production-56hi"&gt;Appwrite for Production by Appwrite&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  See DevSpace Forum Repo here
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Mr-Georgie"&gt;
        Mr-Georgie
      &lt;/a&gt; / &lt;a href="https://github.com/Mr-Georgie/Dev-Space-Forum"&gt;
        Dev-Space-Forum
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      DevSpace Forum is an online community where you can get your tech related questions answered via video conferencing. You can also talk about the latest technology you're using in live sessions.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
DevSpace Forum · &lt;a href="https://www.npmjs.com/package/react" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/98ed63c9884d96bf0477b9f54f1a71a6bba3cb7bf39fe6d4a87805b11d9743ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e706d2d76362e31342e31332d626c7565" alt="npm version"&gt;&lt;/a&gt; &lt;a href="https://github.com/facebook/react/blob/main/LICENSE"&gt;&lt;img src="https://camo.githubusercontent.com/cdd1e7448caec22a3564b58ee80179eaeb5efb6a149cc268a7e3d15b9f05f52d/68747470733a2f2f696d672e736869656c64732e696f2f686578706d2f6c2f617061" alt="GitHub license"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;DevSpace Forum is an online community where you can get your tech related questions answered via video conferencing. You can also talk about the latest technology you're using in live sessions.&lt;/p&gt;
&lt;p&gt;Questions on DevSpace can be in the form of "how to's", "getting started", "introduction", "onboarding experience", etc.&lt;/p&gt;
&lt;h2&gt;
Preview&lt;/h2&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://user-images.githubusercontent.com/28518667/167266369-9cd83538-8441-4750-891b-477aa960dd17.gif"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ChcbSQXA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/28518667/167266369-9cd83538-8441-4750-891b-477aa960dd17.gif" alt="devspace"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Description&lt;/h2&gt;
&lt;p&gt;The DevSpace Forum will be made with the following technologies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React &amp;amp; React-Router (FrontEnd)&lt;/li&gt;
&lt;li&gt;TailWind CSS&lt;/li&gt;
&lt;li&gt;AppWrite (API, Authentication &amp;amp; Database)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;p&gt;In the project directory, you can run:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm start&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This will install all the dependencies from the package.json file&lt;/p&gt;
&lt;h2&gt;
Contributing&lt;/h2&gt;
&lt;p&gt;DevSpace Forum is open sourced so it can be used by others. See the LICENSE file for terms and conditions&lt;/p&gt;
&lt;p&gt;Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
&lt;h2&gt;
License&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.apache.org/licenses/LICENSE-2.0" rel="nofollow"&gt;Apache-2 permissive license&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Mr-Georgie/Dev-Space-Forum"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>react</category>
      <category>appwritehack</category>
      <category>opensource</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Dev x Appwrite Hackathon: #3 CORS Challenges when using Appwrite on Gitpod</title>
      <dc:creator>Georgie</dc:creator>
      <pubDate>Thu, 28 Apr 2022 21:27:24 +0000</pubDate>
      <link>https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-3-cors-challenges-with-appwrite-backend-2kii</link>
      <guid>https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-3-cors-challenges-with-appwrite-backend-2kii</guid>
      <description>&lt;p&gt;Hi friends!&lt;/p&gt;

&lt;p&gt;This is the third post of the series &lt;a href="https://dev.to/georgeisiguzo/series/17812"&gt;DevSpaceForum: An Online Community built with Appwrite x React x TailWindCSS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, I'll write about the several attempts I made to overcome CORS errors when using the Appwrite Web SDK.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Appwrite Setup
&lt;/h3&gt;

&lt;p&gt;I installed Appwrite Backend as a service (BaaS) on Gitpod. This was so hassle-free. The installation and setup were fast and I was loving it.&lt;/p&gt;

&lt;p&gt;The reason I didn't install Appwrite on my local machine was that my local machine's speed has declined over the years and it gets painfully slow most times.&lt;/p&gt;

&lt;p&gt;Kudos to the Appwrite team for making it very easy to install virtually.&lt;/p&gt;

&lt;p&gt;After going through the Appwrite documentation and I was eager to begin the integration with my front end.&lt;/p&gt;

&lt;p&gt;Then came CORS errors.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please note: CORS stands for Cross-Origin Resource Sharing and it is a cyber security mechanism that allows/prevents one origin to access a resource from a different origin. Read more about it &lt;a href="https://dev.to/chuckchoiboi/demystifying-cross-origin-resource-sharing-cors-4lpj"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are the attempts I made to resolve the errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 1: Using Appwrite Web SDK directly in my React Frontend.
&lt;/h3&gt;

&lt;p&gt;I attempted to use the Appwrite SDK directly in my react app so I did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On my Appwrite project on gitpod, I added a web platform specifying the domain that will interact with the platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this case, the domain is localhost since my react frontend is still locally hosted on my machine.&lt;/p&gt;

&lt;p&gt;See the screenshot below for details:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4zcgnq80tj5mbywca0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4zcgnq80tj5mbywca0i.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q9830d9ol5h8owuf6yi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q9830d9ol5h8owuf6yi.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Then I installed Appwrite web SDK on my react app.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;See Appwrite documentation &lt;a href="https://appwrite.io/docs/getting-started-for-web" rel="noopener noreferrer"&gt;here&lt;/a&gt; for the complete steps so setup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Normally, since I specified the domain as localhost, I am not supposed to have any cors issue because the specified domain will be whitelisted by Appwrite and will be given full permission to access the project's resources.&lt;/p&gt;

&lt;p&gt;I'm yet to find out where the issue is from, probably I need to do a little tweaking on the &lt;code&gt;.env&lt;/code&gt; file of my gitpod workspace.&lt;/p&gt;

&lt;p&gt;CORS bugged me for a whole night. I'm not one to back out of a challenge let alone a bug but due to my 9-5 job (non-tech), I knew I had to try something else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 2: Using Appwrite Web SDK in a Proxy server (API)
&lt;/h3&gt;

&lt;p&gt;The last time I encountered CORS issues when communicating with a remote backend, I had to set up a proxy API that would bypass the CORS mechanism.&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://dev.to/will_yama/how-to-overcome-cors-errors-2nh9"&gt;article by William Sayama&lt;/a&gt; was very helpful in setting up one.&lt;/p&gt;

&lt;p&gt;This was what I did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created an express server&lt;/li&gt;
&lt;li&gt;Installed Appwrite Web SDK on it. I installed &lt;code&gt;node-appwrite&lt;/code&gt; this time since I will be using a server to interact with Appwrite API.&lt;/li&gt;
&lt;li&gt;Added the necessary configurations to it&lt;/li&gt;
&lt;li&gt;Installed other dependencies like CORS to bypass CORS issues&lt;/li&gt;
&lt;li&gt;Created endpoints on the server that my react app can call&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is how the express server works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It serves as an intermediary between my Appwrite backend and my react frontend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The react frontend sends HTTP requests to the expressJs server, the server sends an equivalent request to Appwrite, Appwrite responds appropriately and the server sends Appwrite's response back to the react app.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using this method, I was able to create user accounts and I could access all endpoints on the Appwrite rest API.&lt;/p&gt;

&lt;p&gt;The challenge with this attempt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I couldn't implement user authentication using &lt;code&gt;createSession&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How so?&lt;/p&gt;

&lt;p&gt;I could access the &lt;code&gt;createSession&lt;/code&gt; endpoint which would return the access tokens that I can use to authenticate subsequent user requests to the server but... &lt;/p&gt;

&lt;p&gt;I couldn't transfer these tokens received by my express server to my react app so that it can use the tokens in subsequent requests.&lt;/p&gt;

&lt;p&gt;Still, with little time on my hands, I had to think of another way to go about this quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 3: Disabling CORS on Chrome (My temporary Solution)
&lt;/h3&gt;

&lt;p&gt;StackOverflow came to the rescue here. I was able to disable CORS  by creating a Chrome shortcut on windows and editing its properties.&lt;/p&gt;

&lt;p&gt;See how to do so &lt;a href="https://stackoverflow.com/questions/3102819/disable-same-origin-policy-in-chrome" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I don't need a proxy API and my react app can interact with the Appwrite API.&lt;/p&gt;

&lt;p&gt;At the moment, I have no bugs or errors, or warnings. I hope it stays that way.&lt;/p&gt;

&lt;p&gt;Now I can focus on implementing Appwrite services in my app.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I could have avoided the issues altogether
&lt;/h3&gt;

&lt;p&gt;If I had installed docker on my local machine and then installed Appwrite on it, then I wouldn't have CORS issues while developing.&lt;/p&gt;

&lt;p&gt;In production, I can install Appwrite on digital ocean. I have seen several articles and tutorials on how to do so. I don't think I'll have any issue with it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Production in this terms means hosting both my frontend and backend on live servers (or hosting them virtually).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you've faced any of the above-mentioned challenges and you were able to resolve them do let me know in the comment section.&lt;/p&gt;

&lt;p&gt;For now, let me go back to completing the app. It's almost submission time.&lt;/p&gt;

&lt;p&gt;I'll be writing one or two more articles in this series.&lt;/p&gt;

&lt;p&gt;Do stay tuned! &lt;/p&gt;

</description>
      <category>appwritehack</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Dev x Appwrite Hackathon: #2 UI with ReactJs &amp; TailWindCSS</title>
      <dc:creator>Georgie</dc:creator>
      <pubDate>Wed, 20 Apr 2022 17:44:31 +0000</pubDate>
      <link>https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-2-ui-with-reactjs-tailwindcss-4gic</link>
      <guid>https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-2-ui-with-reactjs-tailwindcss-4gic</guid>
      <description>&lt;p&gt;Welcome back 👋&lt;/p&gt;

&lt;p&gt;If you've checked out part 1 of this series &lt;a href="https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-1-introduction-1lda"&gt;here&lt;/a&gt;, you probably must have visited the GitHub repository.&lt;/p&gt;

&lt;p&gt;Notice any changes?&lt;/p&gt;

&lt;p&gt;I have added the code for a simple UI. Just a welcome page.&lt;/p&gt;

&lt;p&gt;See it here below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jx44jzs8nljxu31s80b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jx44jzs8nljxu31s80b.png" alt="DevSpace Forum Welcome Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How did I do so?&lt;/p&gt;

&lt;h2&gt;
  
  
  Here's a summary of how I did it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  #1 Create a new React Project
&lt;/h3&gt;

&lt;p&gt;See this link &lt;a href="https://reactjs.org/docs/create-a-new-react-app.html" rel="noopener noreferrer"&gt;here&lt;/a&gt; on how to create a new react project.&lt;/p&gt;

&lt;p&gt;It's pretty straightforward.&lt;/p&gt;

&lt;h3&gt;
  
  
  #2 Add Tailwind CSS to your React Project
&lt;/h3&gt;

&lt;p&gt;See this link &lt;a href="https://tailwindcss.com/docs/guides/create-react-app" rel="noopener noreferrer"&gt;here&lt;/a&gt; for quick steps to add tailwindcss to your app.&lt;/p&gt;

&lt;p&gt;By now, when you run &lt;code&gt;npm start&lt;/code&gt;, you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F218bv6ea85esjtvnq2wb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F218bv6ea85esjtvnq2wb.png" alt="Successfully add tailwindcss to reactjs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hoping you did it properly and you've got no bugs, let's continue.&lt;/p&gt;

&lt;h3&gt;
  
  
  #3 Creating files, adding contents
&lt;/h3&gt;

&lt;p&gt;Before you proceed, I hope you know the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;rct=j&amp;amp;url=https://create-react-app.dev/docs/importing-a-component/&amp;amp;ved=2ahUKEwiBpNmWl6P3AhVCzBoKHR9nAfIQFnoECAQQAQ&amp;amp;usg=AOvVaw3JVa4lgUtkysXCgn5-pESu" rel="noopener noreferrer"&gt;How to import components in react&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;rct=j&amp;amp;url=https://blog.logrocket.com/code-splitting-in-react-an-overview/&amp;amp;ved=2ahUKEwi2n9Hgl6P3AhVJqxoKHen3BY8QFnoECBkQAQ&amp;amp;usg=AOvVaw3GRrhXBF4PadEuPgSKmBB_" rel="noopener noreferrer"&gt;How to split your react code into components for better readability&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create a new folder inside the &lt;code&gt;src&lt;/code&gt; folder, call it &lt;code&gt;Components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you've built an app with ReactJs before, I'm sure you know ReactJs is all about creating components and reusing them. Hence the need to have a folder where all the components of our app should be.&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;Components&lt;/code&gt;, create two files: &lt;code&gt;Welcome.js&lt;/code&gt; and &lt;code&gt;Toggler.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Welcome.js&lt;/code&gt; components will hold the UI for the welcome page while &lt;code&gt;Toggler.js&lt;/code&gt; handles state logic.&lt;/p&gt;

&lt;p&gt;Toggler.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {Component} from "react"

class Toggler extends Component {

    state = {
        on: this.props.defaultOnValue
    }

    static defaultProps = {
        defaultOnValue: false
    }

    toggle = () =&amp;gt; {
        this.setState(prevState =&amp;gt; ({on: !prevState.on}))
    }

    render() {
        return (
            &amp;lt;div&amp;gt;
                {this.props.children({
                    on: this.state.on, 
                    toggle: this.toggle
                })}
            &amp;lt;/div&amp;gt;
        )
    }
}

export default Toggler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Toggler.js&lt;/code&gt; is a bit advanced ReactJs concept. It is a component that uses render props to pass state to another component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/docs/render-props.html" rel="noopener noreferrer"&gt;See info on render props&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To explain in simple terms, any component passed into &lt;code&gt;Toggler.js&lt;/code&gt; as its child will have access to its &lt;code&gt;on&lt;/code&gt; state and &lt;code&gt;toggle&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Welcome.js&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;import React, { useState } from "react"
import Header from "./WelcomeComponents/Header"
import Main from "./WelcomeComponents/Content"
import Footer from "./SubComponents/Footer"

export default function Welcome() {
    /**
     * This welcome component will show for unauthenticated users
     */

    // this show modal state will determine welcome component UI behaviour when the modals in the &amp;lt;Header/&amp;gt; is active
    const [showModal, setShowModal] = useState(false)

    const showModalHandler = () =&amp;gt; {
        setShowModal(prevState =&amp;gt; !prevState)
    }

    return (
        // Add overflow-hidden to the welcome component UI when modal in &amp;lt;Header/&amp;gt; is active
        &amp;lt;div className={`${showModal ? "overflow-y-hidden h-screen" : " "} app-style`}&amp;gt;
            &amp;lt;Header showModalHandler={showModalHandler}/&amp;gt;
            &amp;lt;Main /&amp;gt;
            &amp;lt;Footer /&amp;gt;
        &amp;lt;/div&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other not to make our &lt;code&gt;Welcome.js&lt;/code&gt; too long, I created sub-components for a &lt;code&gt;Header&lt;/code&gt;, &lt;code&gt;Main&lt;/code&gt; and &lt;code&gt;Footer&lt;/code&gt; section of the welcome page.&lt;/p&gt;

&lt;p&gt;I placed these in two new folders inside the components directory. See the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9tswdjig6j9ino6395aj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9tswdjig6j9ino6395aj.png" alt="code editor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see the &lt;a href="https://github.com/Mr-Georgie/Dev-Space-Forum" rel="noopener noreferrer"&gt;github repo here&lt;/a&gt; to properly view the code structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  #4 How to use Tailwind CSS
&lt;/h3&gt;

&lt;p&gt;Lastly, about Tailwind CSS.&lt;/p&gt;

&lt;p&gt;Tailwind CSS gives you the freedom to specify how you want any part of your UI to look using utility classes.&lt;/p&gt;

&lt;p&gt;To create mobile-first responsive designs, tailwind gives us 3 utilities: &lt;code&gt;sm:&lt;/code&gt;, &lt;code&gt;md:&lt;/code&gt;, &lt;code&gt;lg:&lt;/code&gt; and &lt;code&gt;xl:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These are prefixes that represent small screens, medium screens, large screens, and extra-large screens.&lt;/p&gt;

&lt;p&gt;They are called prefixes because you put them just before other utility classes to specify on what screen that utility class should work e.g &lt;code&gt;md:border&lt;/code&gt; means that on medium screens, there should be a border on that element.&lt;/p&gt;

&lt;p&gt;In my app, the banner section of the welcome page contains two columns: a text and an image-side by side to each other (scroll up to see screenshot)&lt;/p&gt;

&lt;p&gt;To create this, here's my code.&lt;/p&gt;

&lt;p&gt;First for the row that will hold the two columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className="grid grid-col-1 px-16
                lg:grid-cols-12 
                xl:gap-10 xl:my-10 xl:px-24"&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On mobile screens, I specified that the columns appear in a &lt;code&gt;grid&lt;/code&gt;, each column should occupy full width &lt;code&gt;grid-col-1&lt;/code&gt; and there should be padding both left and right &lt;code&gt;px-16&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For large screens (desktop), I divided the columns into 12 &lt;code&gt;grid-cols-12&lt;/code&gt;. I will have to share the 12 columns between the two contents in the row. I'll give the text 7 columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className="lg:col-span-7"&amp;gt;Welcome to DevSpace Forum&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the image 5 columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="..." alt="..." className="lg:col-span-5" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the text will occupy more space than the image&lt;/p&gt;

&lt;p&gt;Then on extra-large screens, I specified the gap between the two contents as 10 &lt;code&gt;gap-10&lt;/code&gt;, margin-top and bottom as 10 &lt;code&gt;my-10&lt;/code&gt;, padding-left and right as 24 &lt;code&gt;px-24&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Okay. Hopefully, you get the gist now but you don't, no worries.&lt;/p&gt;

&lt;p&gt;I will be writing a separate article focused on tailwind CSS.&lt;/p&gt;

&lt;p&gt;For now, I will be integrating my react app (i.e DevSpace forum) with appwrite (backend).&lt;/p&gt;

&lt;p&gt;I'm glad I don't have to write codes for the backend.&lt;/p&gt;

&lt;p&gt;Appwrite console has everything I need.&lt;/p&gt;

&lt;p&gt;Stay tuned for the next article in this series.&lt;/p&gt;

&lt;p&gt;Bye! 👋&lt;/p&gt;

</description>
      <category>appwritehack</category>
      <category>react</category>
      <category>tailwindcss</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Dev x Appwrite Hackathon: #1 Introduction</title>
      <dc:creator>Georgie</dc:creator>
      <pubDate>Wed, 20 Apr 2022 15:35:45 +0000</pubDate>
      <link>https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-1-introduction-1lda</link>
      <guid>https://dev.to/georgeisiguzo/devspaceforum-x-appwrite-part-1-introduction-1lda</guid>
      <description>&lt;h3&gt;
  
  
  Overview of My Submission
&lt;/h3&gt;

&lt;p&gt;Hi there! After a week-long deliberation, I'm entering the &lt;strong&gt;appwrite x dev hackathon&lt;/strong&gt;.😁&lt;/p&gt;

&lt;h4&gt;
  
  
  What I'm building
&lt;/h4&gt;

&lt;p&gt;I call the app DevSpace Forum. &lt;strong&gt;What's it about?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DevSpace Forum is an online community where you can get your tech-related questions answered via video conferencing &lt;em&gt;(or sessions)&lt;/em&gt;. You can also talk about the latest technology you're using in live video sessions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Questions on DevSpace can be in the form of "how to's", "getting started", "introduction", "onboarding experience", etc.&lt;/p&gt;

&lt;p&gt;I know what you're thinking. There's youtube! &lt;em&gt;(and many others)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the difference?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On DevSpace, you can ask coding-related questions like on StackOverflow only that another user gets to provide an answer to your question in a live session.&lt;/p&gt;

&lt;p&gt;That way, you get to ask follow-up questions during the live sessions.&lt;/p&gt;

&lt;p&gt;DevSpace is about asking, sharing, networking, and learning.&lt;/p&gt;

&lt;p&gt;You can also raise a question or tutorial too and let users in the community join your live sessions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Finding loopholes in the idea already (or possibly have a contribution) do share.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Thanks 😁&lt;/p&gt;

&lt;h4&gt;
  
  
  How I will build it
&lt;/h4&gt;

&lt;p&gt;I'll be using the opportunity to learn Tailwind CSS. I've always wanted to use it.&lt;/p&gt;

&lt;p&gt;I'll be sharpening my React skills as well.&lt;/p&gt;

&lt;h4&gt;
  
  
  The inspiration
&lt;/h4&gt;

&lt;p&gt;I've almost completed my React Course on &lt;a href="https://scrimba.com/learn/frontend" rel="noopener noreferrer"&gt;Scrimba&lt;/a&gt; and ever since, I keep getting this urge to share my knowledge.&lt;/p&gt;

&lt;p&gt;I could create a youtube channel for it but how about an app (a forum or community) that is specifically for learning and sharing (I thought to myself)&lt;/p&gt;

&lt;p&gt;Fun fact: You can combine your youtube channel with DevSpace.&lt;/p&gt;

&lt;p&gt;During every video session, the tutor (the person answering or sharing ideas) records the session and can upload it on his youtube channel.&lt;/p&gt;

&lt;p&gt;S/he will also share the link to the record session so that members of the community could watch it at a later time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;This submission is under the &lt;strong&gt;Web2 Wizards Category&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;

&lt;p&gt;Find the GitHub repository 
  here
  &lt;a href="https://github.com/Mr-Georgie/Dev-Space-Forum" rel="noopener noreferrer"&gt;https://github.com/Mr-Georgie/Dev-Space-Forum&lt;/a&gt; 

&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Mr-Georgie" rel="noopener noreferrer"&gt;
        Mr-Georgie
      &lt;/a&gt; / &lt;a href="https://github.com/Mr-Georgie/dev-space-forum" rel="noopener noreferrer"&gt;
        dev-space-forum
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      DevSpace Forum is an online community where you can get your tech related questions answered via video conferencing. You can also talk about the latest technology you're using in live sessions.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;DevSpace Forum · &lt;a href="https://www.npmjs.com/package/react" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/cf2496b8fa99cb247aa4944fed006f6582c26bc7905a0513ae64ec8017230a5c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e706d2d76362e31342e31332d626c7565" alt="npm version"&gt;&lt;/a&gt; &lt;a href="https://github.com/facebook/react/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f500da3698368acb89d7cafed4af8a7e8bb196d87748faadb13ce6db53f63a66/68747470733a2f2f696d672e736869656c64732e696f2f686578706d2f6c2f617061" alt="GitHub license"&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;DevSpace Forum is an online community where you can get your tech related questions answered via video conferencing. You can also talk about the latest technology you're using in live sessions.&lt;/p&gt;
&lt;p&gt;Questions on DevSpace can be in the form of "how to's", "getting started", "introduction", "onboarding experience", etc.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Preview&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/28518667/167266369-9cd83538-8441-4750-891b-477aa960dd17.gif"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F28518667%2F167266369-9cd83538-8441-4750-891b-477aa960dd17.gif" alt="devspace"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Description&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The DevSpace Forum was made with the following technologies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React &amp;amp; React-Router (FrontEnd)&lt;/li&gt;
&lt;li&gt;TailWind CSS&lt;/li&gt;
&lt;li&gt;AppWrite (API, Authentication &amp;amp; Database)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;In the project directory, you can run:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm start&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This will install all the dependencies from the package.json file&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Contributing&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;DevSpace Forum is open sourced so it can be used by others. See the LICENSE file for terms and conditions&lt;/p&gt;
&lt;p&gt;Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;License&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.apache.org/licenses/LICENSE-2.0" rel="nofollow noopener noreferrer"&gt;Apache-2 permissive license&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Mr-Georgie/dev-space-forum" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;This is a series so the next post will be about setting up the user interface&lt;/p&gt;

&lt;h4&gt;
  
  
  Links
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/" rel="noopener noreferrer"&gt;https://appwrite.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;https://tailwindcss.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/getting-started.html" rel="noopener noreferrer"&gt;https://reactjs.org/docs/getting-started.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See ya' in the next post 👋 &lt;/p&gt;

</description>
      <category>appwritehack</category>
      <category>react</category>
      <category>tailwindcss</category>
    </item>
  </channel>
</rss>
