<?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: Bishal Neupane</title>
    <description>The latest articles on DEV Community by Bishal Neupane (@bishaln).</description>
    <link>https://dev.to/bishaln</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%2F720218%2Fc8f11e1c-8999-461d-ba6f-f29c65f374e7.jpeg</url>
      <title>DEV Community: Bishal Neupane</title>
      <link>https://dev.to/bishaln</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bishaln"/>
    <language>en</language>
    <item>
      <title>How does the internet work? Simplified</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Mon, 10 Oct 2022 05:03:21 +0000</pubDate>
      <link>https://dev.to/bishaln/how-does-the-internet-work-simplified-7d</link>
      <guid>https://dev.to/bishaln/how-does-the-internet-work-simplified-7d</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: In an attempt to simplify the workings of the internet. I've not included the technical jargon and avoided many parts of the internet.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So, What is the Internet anyways?
&lt;/h2&gt;

&lt;p&gt;If you’re imagining cloud stuff then please don’t that's the most incorrect picture of the internet. Internet is basically just wires which might be copper wire, fiber optics, or a cell phone network.&lt;/p&gt;

&lt;p&gt;Computers connected to this wire can communicate with each other thus allowing people to share resources, information, etc. &lt;/p&gt;

&lt;p&gt;There are dedicated computers known as servers that are directly connected to the internet and store webpages, images, videos, etc. These servers have unique IP addresses. These IP addresses are like home addresses as you can use them to reach the server e.g 142.250.196.78. These numbers are difficult to remember so we’ve names basically these names are mapped into the IP address like.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://google.com"&gt;google.com&lt;/a&gt; → 142.250.196.78. We’ll talk about this conversion in another blog.&lt;/p&gt;

&lt;h3&gt;
  
  
  A youtube video journey story to discuss How the internet works?
&lt;/h3&gt;

&lt;p&gt;Have you ever imagined or wondered how the youtube videos you would like to watch land on your computer so seamlessly? Here let's dig into the networking side of things.&lt;/p&gt;

&lt;p&gt;This is a simplified illustration of what happens when you request a video on youtube.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5UXE5N2D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3yl4pikdedy915zmraes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5UXE5N2D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3yl4pikdedy915zmraes.png" alt="Image description" width="880" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First step: It goes through your router at your home.&lt;/p&gt;

&lt;p&gt;Second step: Your router forwards that request to your ISP (Internet Service Provider).&lt;/p&gt;

&lt;p&gt;Third step: From here your ISP may route your request anywhere around the world mostly to another ISP from where it has bought the bandwidth. So your request to youtube is now going to hop to multiple routers before it reaches its destination i.e YouTubes server.&lt;/p&gt;

&lt;p&gt;you can use a program called traceroute to see how your request gets to youtube servers and how many hops it makes to reach youtube.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;traceroute youtube.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fourth Step: The youtube server gets your request and sends back the video you requested the video file travels to your computer using the IP address. Remember while sending a request you give both the destination and source IP address here the source being your computer. &lt;/p&gt;

&lt;p&gt;All the data on the internet are transferred as packets. First, the video file is divided into packets and then sent across the internet, and when it lands on your computer. The data is reassembled this magic is done by the protocols. About which we’ll discuss in another blog post. &lt;/p&gt;

&lt;p&gt;This was a simplified version of how the internet works.&lt;br&gt;
If you want to dive deeper into the technical details of how the internet really works then: &lt;br&gt;
&lt;a href="https://web.stanford.edu/class/msande91si/www-spr04/readings/week1/InternetWhitepaper.htm"&gt;https://web.stanford.edu/class/msande91si/www-spr04/readings/week1/InternetWhitepaper.htm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/How_does_the_Internet_work"&gt;https://developer.mozilla.org/en-US/docs/Learn/Common_questions/How_does_the_Internet_work&lt;/a&gt;&lt;/p&gt;

</description>
      <category>internet</category>
    </item>
    <item>
      <title>Deploying strapi project on heroku</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Sun, 28 Nov 2021 10:15:10 +0000</pubDate>
      <link>https://dev.to/bishaln/deploying-strapi-project-on-heroku-b08</link>
      <guid>https://dev.to/bishaln/deploying-strapi-project-on-heroku-b08</guid>
      <description>&lt;p&gt;This is the eight blog post on the series of blog post I am posting about strapi,nextjs, and tailwind. We are recreating my portfolio/blogpost page that along the way we'll learn the fundamentals of strapi,nextjs, and tailwind. You can check it out at &lt;a href="https://myportfolioandblog.vercel.app/"&gt;myportfolio&lt;/a&gt; If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series.&lt;/p&gt;

&lt;p&gt;In this blog post we're going to deploy our strapi project on heroku. So if you don't have heroku account then go ahead and create also don't forget to install the heroku cli.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku version

//output --&amp;gt; heroku/7.59.1 linux-x64 node-v12.21.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go ahead and login&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's create a heroku app for that name of your app must be unique&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku create nameofyourapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within your strapi project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku git:remote -a nameofyourapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's setup postgres db&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku addons:create heroku-postgresql:hobby-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to set database variable so that stapi can connect to our database for that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add pg-connection-string
or
npm i pg-connection-string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also need seprate database config for database so,&lt;br&gt;
Inside Path: ./config/env/production/database.js add this&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--682ZCR0B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxcseup20h0lkilllqh7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--682ZCR0B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxcseup20h0lkilllqh7.png" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const parse = require('pg-connection-string').parse;
const config = parse(process.env.DATABASE_URL);

module.exports = ({ env }) =&amp;gt; ({
  defaultConnection: 'default',
  connections: {
    default: {
      connector: 'bookshelf',
      settings: {
        client: 'postgres',
        host: config.host,
        port: config.port,
        database: config.database,
        username: config.user,
        password: config.password,
        ssl: {
          rejectUnauthorized: false,
        },
      },
      options: {
        ssl: true,
      },
    },
  },
});

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

&lt;/div&gt;



&lt;p&gt;This sets the node enviroment variable to production&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku config:set NODE_ENV=production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add ./config/env/production/server.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = ({ env }) =&amp;gt; ({
  url: env('MY_HEROKU_URL'),
});

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku config:set MY_HEROKU_URL=$(heroku info -s | grep web_url | cut -d= -f2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add pg
or
npm i pg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "Update database config"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push heroku master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;And that is it about Deploying strapi project on heroku. In another blog post, we'll deploy nextjs to vercel. If you have any problem with this code and then let me know in the discussion.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Rendering mdx content using react-markdown</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Sun, 28 Nov 2021 09:41:53 +0000</pubDate>
      <link>https://dev.to/bishaln/rendering-mdx-content-using-react-markdown-91f</link>
      <guid>https://dev.to/bishaln/rendering-mdx-content-using-react-markdown-91f</guid>
      <description>&lt;p&gt;This is the seventh blog post on the series of blog post I am posting about strapi,nextjs, and tailwind. We are recreating my portfolio/blogpost page that along the way we'll learn the fundamentals of strapi,nextjs, and tailwind. You can check it out at &lt;a href="https://myportfolioandblog.vercel.app/"&gt;myportfolio&lt;/a&gt; If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series.&lt;/p&gt;

&lt;p&gt;In this blog post we're going to create the blog page that renders the mdx content&lt;br&gt;
We're going to make use of react-markdown and remark-gfm to render mdx content well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react-markdown remark-gfm
or
npm i react-markdown remark-gfm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's create a folder blog inside the pages directory and within blog folder create file with [slug].tsx name. So that we can fetch blog using getStaticProps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { gql } from 'graphql-request';

export const blogPathsQuery = gql`
  query BlogPaths {
    posts {
      slug
    }
  }
`;

export const blogPageQuery = gql`
  query Blog($slug: String!) {
    posts(where: { slug: $slug }) {
      title
      slug
      description
      updated_at
      topics
      author {
        name
        bio
        avatar {
          formats
        }
      }
      playlist {
        posts {
          updated_at
          title
          slug
          description
          topics
        }
      }
    }
  }
`;

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

&lt;/div&gt;



&lt;p&gt;Now inside the [slug].tsx add 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 request from 'graphql-request';
import { DateTime } from 'luxon';
import { GetStaticProps } from 'next';
import NextImage from 'next/image';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';

import { BlogPathsQuery, BlogQuery } from '../../gql/graphql';
import { blogPageQuery, blogPathsQuery } from '../../queries/blog';
import { timetoRead } from '../../util/calculateTimeToRead';
import { GobackButton } from '../playlists';
import { Link } from '../../components/Link';
import { BlogCard } from '../../components/BlogCard';

export async function getStaticPaths() {
  const paths: BlogPathsQuery = await request(
    'http://localhost:1337/graphql',
    blogPathsQuery
  );
  const pathFormat: any = [];
  paths.posts?.forEach((path) =&amp;gt;
    pathFormat.push({ params: { slug: path?.slug } })
  );
  return {
    paths: pathFormat,
    fallback: false,
  };
}

export const getStaticProps: GetStaticProps = async (context) =&amp;gt; {
  const posts: BlogQuery = await request(
    'http://localhost:1337/graphql',
    blogPageQuery,
    {
      slug: context?.params?.slug,
    }
  );
  return {
    props: posts,
  };
};

function Playlist({ posts }: BlogQuery) {
  const post = posts![0];
  const formattedDate = DateTime.fromISO(post?.updated_at).toFormat('DD');
  const approxReadingTime = timetoRead(post?.description!);

  return (
    &amp;lt;div className='container mx-auto sm:p-5'&amp;gt;
      &amp;lt;div className='border-2 border-gray-500'&amp;gt;
        &amp;lt;GobackButton /&amp;gt;
        &amp;lt;div className='flex'&amp;gt;
          &amp;lt;NextImage
            src={post?.author?.avatar?.formats.thumbnail.url}
            height={post?.author?.avatar?.formats.thumbnail.height}
            width={post?.author?.avatar?.formats.thumbnail.width}
            className='rounded-full'
          /&amp;gt;
          &amp;lt;div&amp;gt;
            &amp;lt;p className='capitalize text-2xl text-gray-800'&amp;gt;
              {post?.author?.name}
            &amp;lt;/p&amp;gt;
            &amp;lt;p className='text-gray-500'&amp;gt;{post?.author?.bio}&amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        {/* blogsection */}
        &amp;lt;section className='px-5'&amp;gt;
          &amp;lt;div&amp;gt;
            &amp;lt;h1 className='my-2 text-3xl md:text-5xl text-gray-800'&amp;gt;
              {post?.title}
            &amp;lt;/h1&amp;gt;
            &amp;lt;p className='text-sm text-gray-400'&amp;gt;
              Last Updated {formattedDate}
            &amp;lt;/p&amp;gt;
            &amp;lt;p className='text-sm text-gray-500'&amp;gt;
              ~{approxReadingTime}{' '}
              {approxReadingTime &amp;gt; 1 ? 'minutes' : 'minute'} read
            &amp;lt;/p&amp;gt;
            &amp;lt;div className='relative h-full'&amp;gt;&amp;lt;/div&amp;gt;
            &amp;lt;ReactMarkdown
              components={{
                a: ({ node, ...props }) =&amp;gt; {
                  console.log(props);
                  return (
                    &amp;lt;Link
                      {...props}
                      href={props.href!}
                      className='text-green-500'
                    /&amp;gt;
                  );
                },
              }}
              remarkPlugins={[[remarkGfm, { singleTilde: false }]]}
            &amp;gt;
              {post?.description!}
            &amp;lt;/ReactMarkdown&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/section&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div className='border-2 border-gray-400 p-2 my-5'&amp;gt;
        &amp;lt;h4 className='text-2xl text-gray-600 my-3'&amp;gt;Some related posts&amp;lt;/h4&amp;gt;
        &amp;lt;div className='space-y-4 md:space-y-0 md:grid gap-4 md:grid-cols-2'&amp;gt;
          {post?.playlist?.posts?.map((post) =&amp;gt; {
            if (posts![0]?.title === post?.title) return;
            return (
              &amp;lt;BlogCard
                title={post?.title!}
                description={post?.description!}
                slug={post?.slug!}
                topics={post?.topics!}
                updated_at={post?.updated_at!}
                key={post?.slug}
              /&amp;gt;
            );
          })}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;And that is it about Rendering mdx content using react-markdown. In another blog post, we'll deploy strapi to heroku and nextjs to vercel. If you have any problem with this code and then let me know in the discussion.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>mdx</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using getStaticProps and getStaticPaths for static site generation (ssg) in nextjs</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Fri, 19 Nov 2021 11:03:13 +0000</pubDate>
      <link>https://dev.to/bishaln/using-getstaticprops-and-getstaticpaths-for-static-site-generation-ssg-in-nextjs-3d4a</link>
      <guid>https://dev.to/bishaln/using-getstaticprops-and-getstaticpaths-for-static-site-generation-ssg-in-nextjs-3d4a</guid>
      <description>&lt;p&gt;This is the sixth blog post on the series of blog post I am posting about strapi,nextjs, and tailwind. We are recreating my portfolio/blogpost page that along the way we'll learn the fundamentals of strapi,nextjs, and tailwind. You can check it out at &lt;a href="https://myportfolioandblog.vercel.app/"&gt;myportfolio&lt;/a&gt; If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series.&lt;/p&gt;

&lt;p&gt;If you've not gone through the previous blog posts then make sure to check them out&lt;/p&gt;

&lt;p&gt;In this blog post, we're going to build two pages in our blog/portfolio site &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Playlists - This will show all the playlists along with recent three blogs&lt;/li&gt;
&lt;li&gt;Playlist  - This will show all the posts on a particular playlist. We'll use dynamic SSG for this page&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Playlists page
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---5KO5A_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n15mjk6r4s9fdpmybs4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---5KO5A_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n15mjk6r4s9fdpmybs4g.png" alt="" width="880" height="430"&gt;&lt;/a&gt;&lt;br&gt;
So let's first build the playlists page for that let's write the query which will fetch the required data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { gql } from 'graphql-request';

export const playlistsQuery = gql`
  query Playlists {
    playlists {
      title
      description
      id
      slug
      posts(sort: "updated_at:desc", limit: 3) {
        updated_at
        title
        slug
        description
        topics
      }
    }
  }
`;

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

&lt;/div&gt;



&lt;p&gt;Create a file playlists.tsx inside the pages and add the following 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 { request } from 'graphql-request';
import { useRouter } from 'next/dist/client/router';
import React from 'react';
import Link from 'next/link';

import { BlogCard } from '../components/BlogCard';
import { PlaylistsQuery } from '../gql/graphql';
import { playlistsQuery } from '../queries/playlists';

export const getStaticProps = async () =&amp;gt; {
  const data: PlaylistsQuery = await request(
    'http://localhost:1337/graphql',
    playlistsQuery
  );

  return { props: data };
};

function playlists({ playlists }: PlaylistsQuery) {
  return (
    &amp;lt;div className='p-2 container sm:mx-auto'&amp;gt;
      &amp;lt;GobackButton /&amp;gt;
      &amp;lt;main&amp;gt;
        &amp;lt;div className='space-y-2'&amp;gt;
          &amp;lt;h1 className='text-4xl'&amp;gt;Welcome to Blog playlist&amp;lt;/h1&amp;gt;
          &amp;lt;h4 className='text-md text-gray-500'&amp;gt;
            A playlist is series of blogpost where I write about particular tool
            or subject
          &amp;lt;/h4&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div className='my-10'&amp;gt;
          {playlists?.map((playlist) =&amp;gt; (
            &amp;lt;div className='my-10' key={playlist?.id}&amp;gt;
              &amp;lt;Link href={`/playlist/${playlist?.slug}`} passHref&amp;gt;
                &amp;lt;h3 className='hover:underline cursor-pointer text-3xl capitalize'&amp;gt;
                  {playlist?.title}
                &amp;lt;/h3&amp;gt;
              &amp;lt;/Link&amp;gt;
              &amp;lt;div className='md:grid md:grid-cols-2 md:gap-3 xl:grid-cols-3'&amp;gt;
                {playlist?.posts?.map((post) =&amp;gt; (
                  &amp;lt;div key={post?.slug} className='my-2 mx-2 h-full'&amp;gt;
                    &amp;lt;BlogCard
                      slug={post?.slug!}
                      title={post?.title!}
                      description={post?.description!}
                      topics={post?.topics!}
                      updated_at={post?.updated_at!}
                    /&amp;gt;
                  &amp;lt;/div&amp;gt;
                ))}
              &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export const GobackButton = () =&amp;gt; {
  const router = useRouter();
  return (
    &amp;lt;button
      onClick={() =&amp;gt; router.back()}
      className='text-green-500 hover:bg-gray-200 rounded-md p-2'
    &amp;gt;
      &amp;amp;larr; go back
    &amp;lt;/button&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Playlist page
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XWxaxQhI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45wxgu2uxbs9vgufm016.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XWxaxQhI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45wxgu2uxbs9vgufm016.png" alt="Image description" width="880" height="428"&gt;&lt;/a&gt;&lt;br&gt;
We'll require two different queries first one to just get the slugs for different playlist page and the second one for the actual data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { gql } from 'graphql-request';

export const playlistPathsQuery = gql`
  query PlaylistPaths {
    playlists {
      slug
    }
  }
`;

export const playlistQuery = gql`
  query Playlist($slug: String!) {
    playlists(where: { slug: $slug }) {
      title
      description
      slug
      posts(sort: "updated_at:desc") {
        id
        updated_at
        title
        slug
        description
        topics
      }
    }
  }
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll use the first query to dynamically build the pages and the second one for the actual data that we need&lt;br&gt;
So go ahead and create a folder inside the pages directory and name it playlist and inside the folder create [slug].tsx file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//[slug].tsx file

import request from 'graphql-request';
import { GetStaticProps } from 'next';
import { BlogCard } from '../../components/BlogCard';

import {
  PlaylistPathsQuery,
  PlaylistQuery,
  PlaylistsQuery,
} from '../../gql/graphql';
import { playlistPathsQuery, playlistQuery } from '../../queries/playlist';
import { GobackButton } from '../playlists';

export async function getStaticPaths() {
  const paths: PlaylistPathsQuery = await request(
    'http://localhost:1337/graphql',
    playlistPathsQuery
  );
  const pathFormat: any = [];
  paths.playlists?.forEach((path) =&amp;gt;
    pathFormat.push({ params: { slug: path?.slug } })
  );
  return {
    paths: pathFormat,
    fallback: false,
  };
}

export const getStaticProps: GetStaticProps = async (context) =&amp;gt; {
  const posts: PlaylistQuery = await request(
    'http://localhost:1337/graphql',
    playlistQuery,
    {
      slug: context?.params?.slug,
    }
  );
  return {
    props: posts,
  };
};

function Playlist({ playlists }: PlaylistsQuery) {
  console.log(playlists);
  const playlist = playlists![0];
  return (
    &amp;lt;div className='p-2'&amp;gt;
      &amp;lt;GobackButton /&amp;gt;
      &amp;lt;div className='space-y-2'&amp;gt;
        &amp;lt;h1 className='text-4xl capitalize'&amp;gt;{playlist?.title}&amp;lt;/h1&amp;gt;
        &amp;lt;h3 className='text-gray-500'&amp;gt;{playlist?.description}&amp;lt;/h3&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div className='space-y-2 md:grid md:grid-cols-2 md:gap-4 md:items-center xl:grid-cols-3'&amp;gt;
        {playlist?.posts?.map((post) =&amp;gt; (
          &amp;lt;BlogCard
            key={post?.slug!}
            title={post?.title!}
            description={post?.description!}
            updated_at={post?.updated_at!}
            topics={post?.topics!}
            slug={post?.slug!}
          /&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Playlist;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;And that is it about Using getStaticProps and getStaticPaths for static site generation (SSG) in nextjs. In another blog post, we'll create the actual blog page. If you have any problem with this code and then let me know in the discussion.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building the landing page for my portfolio/blog website</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Fri, 19 Nov 2021 10:33:34 +0000</pubDate>
      <link>https://dev.to/bishaln/building-the-landing-page-for-my-portfolioblog-webiste-4l1m</link>
      <guid>https://dev.to/bishaln/building-the-landing-page-for-my-portfolioblog-webiste-4l1m</guid>
      <description>&lt;p&gt;This is the fifth blog post on the series of blog post I am posting about strapi,nextjs, and tailwind. We are recreating my portfolio/blogpost page that along the way we'll learn the fundamentals of strapi,nextjs, and tailwind. You can check it out at &lt;a href="https://myportfolioandblog.vercel.app/"&gt;myportfolio&lt;/a&gt; If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series.&lt;/p&gt;

&lt;p&gt;If you've not gone through the previous blog posts then make sure to check them out&lt;/p&gt;

&lt;p&gt;In this blog post, we're going to create the landing page using nextjs and tailwindcss so let's write the graphql query to fetch all the required data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { gql } from 'graphql-request';

export const homePageQuery = gql`
  query HomePage {
    homepage {
      creditText
      Hero {
        title
        navlinks
        profile {
          url
          height
          width
        }
      }
      About {
        work
        blogs
        watch
        email
      }
      Project {
        title
        description
        tools
        image {
          url
          height
          width
        }
        url
        bg {
          url
        }
      }
      Contact {
        email
        insta
        linkedin
        twitter
        youtube
        title
      }
    }
    posts(sort: "updated_at:desc", limit: 3) {
      updated_at
      title
      slug
      description
      topics
    }
  }
`;

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

&lt;/div&gt;



&lt;p&gt;Now let's generate the type information using graphql codegen use&lt;br&gt;
If you've not gone through the generating type info blog post then you can check that out here &lt;a href="https://dev.to/bishaln/generate-type-information-from-gql-graphql-query-using-graphql-generator-3n9k"&gt;Type gen blog post&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It's time to use the nextjs's getStaticProps function which will allow us to make the graphql request on the server during the build process. We can use the getStaticProps 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;export const getStaticProps = async () =&amp;gt; {
  const data: HomePageQuery = await request(
    'http://localhost:1337/graphql',
    homePageQuery
  );

  return { props: data };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the request comes from the graphql-request package and HomePageQuery is the type that was generated by graphql-codegen. This will fetch the data and pass it to the page as a prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { request } from 'graphql-request';
import { homePageQuery } from '../queries/homepage';
import { HomePageQuery, Post } from '../gql/graphql';
import React from 'react';
import NextImage from 'next/image';
import { Link } from '../components/Link';
import { Button } from '../components/Button';
import { BlogCard } from '../components/BlogCard';
import {
  AiFillInstagram,
  AiFillYoutube,
  AiOutlineTwitter,
} from 'react-icons/ai';
import { GrMail } from 'react-icons/gr';

export const getStaticProps = async () =&amp;gt; {
  const data: HomePageQuery = await request(
    'http://localhost:1337/graphql',
    homePageQuery
  );

  return { props: data };
};

const Home = ({ homepage, posts }: HomePageQuery) =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div className='container sm:mx-auto'&amp;gt;
        &amp;lt;main&amp;gt;
          &amp;lt;section id='hero'&amp;gt;
            &amp;lt;div className='rounded-md mt-5 bg-hero'&amp;gt;
              {/* navLinks */}
              &amp;lt;div className='flex space-x-4 justify-end p-4 mx-4'&amp;gt;
                {homepage?.Hero?.navlinks?.split(',').map((nav) =&amp;gt; (
                  &amp;lt;Link href={nav == 'blog' ? '/playlists' : '#'} key={nav}&amp;gt;
                    {nav}
                  &amp;lt;/Link&amp;gt;
                ))}
              &amp;lt;/div&amp;gt;

              {/* titleandprofile */}
              &amp;lt;div className='flex flex-col sm:flex-row mt-10 justify-between'&amp;gt;
                &amp;lt;h1
                  style={{ lineHeight: '1.3' }}
                  className='text-gray-800 xl:ml-32
             text-opacity-95 text-3xl md:text-5xl lg:text-6xl mx-4 max-w-lg'
                &amp;gt;
                  {homepage?.Hero?.title}
                &amp;lt;/h1&amp;gt;
                &amp;lt;NextImage
                  src={homepage?.Hero?.profile?.url!}
                  alt='myprofile'
                  height={`${homepage?.Hero?.profile?.height!}`}
                  width={homepage?.Hero?.profile?.width!}
                /&amp;gt;
              &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/section&amp;gt;
        &amp;lt;/main&amp;gt;
        {/* worksection */}
        &amp;lt;section id='work'&amp;gt;
          &amp;lt;div
            className='bg-indigo-300 my-10 rounded-lg
         grid sm:grid-rows-2 sm:grid-cols-2 p-4 gap-2 xl:pl-32'
          &amp;gt;
            &amp;lt;div className='space-y-1 my-4'&amp;gt;
              &amp;lt;h1 className='text-5xl'&amp;gt;Work.&amp;lt;/h1&amp;gt;
              &amp;lt;p className='ml-2 max-w-md text-gray-600'&amp;gt;
                {homepage?.About?.work}
              &amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div className='space-y-1'&amp;gt;
              &amp;lt;h1 className='text-5xl'&amp;gt;Blogs.&amp;lt;/h1&amp;gt;
              &amp;lt;p className='max-w-md text-gray-600'&amp;gt;{homepage?.About?.blogs}&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div className='space-y-1'&amp;gt;
              {/* &amp;lt;h1 className='text-5xl'&amp;gt;Work.&amp;lt;/h1&amp;gt; */}
              &amp;lt;div className='h-10'&amp;gt;&amp;lt;/div&amp;gt;
              &amp;lt;div className='ml-2 max-w-md text-gray-600'&amp;gt;
                &amp;lt;Link
                  className='inline-block text-blue-600'
                  href={`mailto:${homepage?.Contact?.email}`}
                &amp;gt;
                  Email me
                &amp;lt;/Link&amp;gt;{' '}
                {homepage?.About?.email}
              &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div className='space-y-1'&amp;gt;
              &amp;lt;h1 className='text-5xl'&amp;gt;Watch.&amp;lt;/h1&amp;gt;
              &amp;lt;p className='ml-2 max-w-md text-gray-600'&amp;gt;
                {homepage?.About?.watch}
              &amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/section&amp;gt;
      &amp;lt;/div&amp;gt;
      {/* projectsection */}
      &amp;lt;section id='project'&amp;gt;
        {homepage?.Project?.map((project) =&amp;gt; {
          return (
            &amp;lt;div
              key={project?.title}
              className='relative h-screen grid grid-rows-2 grid-cols-1 md:grid-rows-1 md:grid-cols-2 
                text-white justify-items-center place-items-center p-2'
            &amp;gt;
              &amp;lt;NextImage
                src={project?.bg?.url!}
                layout='fill'
                objectPosition='center'
                objectFit='cover'
                className='z-0 bg-blend-overlay bg-gray-600'
              /&amp;gt;
              &amp;lt;div className='z-10 place-self-start p-2 md:p-10'&amp;gt;
                &amp;lt;h3 className='text-4xl sm:text-5xl'&amp;gt;{project?.title}&amp;lt;/h3&amp;gt;
                &amp;lt;p className='text-sm sm:text-lg sm:max-w-sm'&amp;gt;
                  {project?.description}
                &amp;lt;/p&amp;gt;
                &amp;lt;Link href={`${project?.url}`} className='text-blue-400 '&amp;gt;
                  {project?.url}
                &amp;lt;/Link&amp;gt;
                &amp;lt;div className='flex uppercase space-x-4'&amp;gt;
                  {project?.tools?.split(',').map((tool) =&amp;gt; (
                    &amp;lt;p key={tool} className='bg-gray-500 px-1 rounded-sm'&amp;gt;
                      {tool}
                    &amp;lt;/p&amp;gt;
                  ))}
                &amp;lt;/div&amp;gt;
              &amp;lt;/div&amp;gt;
              &amp;lt;div className='-mt-40 md:-mt-0'&amp;gt;
                &amp;lt;NextImage
                  src={`${project?.image?.url!}`}
                  height={project?.image?.height!}
                  width={project?.image?.width!}
                /&amp;gt;
              &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
          );
        })}
      &amp;lt;/section&amp;gt;
      {/* recentblogs */}

      &amp;lt;section&amp;gt;
        &amp;lt;div className='p-5 bg-gradient-to-tr from-blue-300 to-indigo-500  my-10'&amp;gt;
          &amp;lt;div
            className='p-2 grid gap-5 grid-cols-1
           grid-rows-1 md:grid-cols-2 lg:grid-cols-3  w-full'
          &amp;gt;
            {posts?.map((post) =&amp;gt; (
              &amp;lt;BlogCard
                key={post?.description!}
                updated_at={post?.updated_at!}
                topics={post?.topics!}
                title={post?.title!}
                slug={post?.slug!}
                description={post?.description!}
              /&amp;gt;
            ))}
          &amp;lt;/div&amp;gt;
          &amp;lt;div className='flex justify-end px-4 pb-2'&amp;gt;
            &amp;lt;Button&amp;gt;More Blogs&amp;lt;/Button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/section&amp;gt;

      {/* contact section */}
      &amp;lt;section id='contact'&amp;gt;
        &amp;lt;div className='flex flex-col items-center justify-center my-32'&amp;gt;
          &amp;lt;h4 className='text-6xl'&amp;gt;{homepage?.Contact?.title}&amp;lt;/h4&amp;gt;
          &amp;lt;div className='flex space-x-10 my-4'&amp;gt;
            &amp;lt;Link href={`mailto:${homepage?.Contact?.email}`}&amp;gt;
              &amp;lt;GrMail size={30} color='black' /&amp;gt;
            &amp;lt;/Link&amp;gt;

            &amp;lt;Link href={homepage?.Contact?.insta!}&amp;gt;
              &amp;lt;AiFillInstagram size={30} color='black' /&amp;gt;
            &amp;lt;/Link&amp;gt;

            &amp;lt;Link href={homepage?.Contact?.youtube!}&amp;gt;
              &amp;lt;AiFillYoutube size={30} color='black' /&amp;gt;
            &amp;lt;/Link&amp;gt;

            &amp;lt;Link href={homepage?.Contact?.twitter!}&amp;gt;
              &amp;lt;AiOutlineTwitter size={30} color='black' /&amp;gt;
            &amp;lt;/Link&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;h3 className='flex items-center justify-center my-10'&amp;gt;
            {homepage?.creditText}
          &amp;lt;/h3&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/section&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Home;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;And that is it about building the landing page using tailwindcss and nodejs google. In another blog post, we'll create a Playlists and Playlist page. If you have any problem with this code and then let me know in the discussion.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>nextjs</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Using google storage to store media files in strapi</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Sun, 14 Nov 2021 09:59:27 +0000</pubDate>
      <link>https://dev.to/bishaln/using-google-bucket-to-store-media-files-in-strapi-2jgm</link>
      <guid>https://dev.to/bishaln/using-google-bucket-to-store-media-files-in-strapi-2jgm</guid>
      <description>&lt;p&gt;This is the fourth blog post on the series of blog post I am posting about strapi,nextjs, and tailwind. We are recreating my portfolio/blogpost page that along the way we'll learn the fundamentals of strapi,nextjs, and tailwind. You can check it out at &lt;a href="https://myportfolioandblog.vercel.app/" rel="noopener noreferrer"&gt;myportfolio&lt;/a&gt; If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series.&lt;/p&gt;

&lt;p&gt;In this blog post, we're going to set up google bucket to store our media files. &lt;br&gt;
So go ahead and install a plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; yarn add strapi-provider-upload-google-cloud-storage
 or 
 npm i strapi-provider-upload-google-cloud-storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we've to create a google cloud bucket and generate the service account for that&lt;br&gt;
I'm using the firebase project which makes it very easy to create a google bucket and generate the service account You can create a google bucket through google cloud console too. If you're using firebase then go to project settings and service account. Click the Generate a new private key. This will download a simple file with JSON data on it. We've to copy that JSON data and stringify it and put it as an environment variable in our strapi app.&lt;br&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%2Fgy5wkoceda0luccrvvd9.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%2Fgy5wkoceda0luccrvvd9.png" alt="json"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's create the env file with GCP_SERVICE_ACCOUNT !&lt;br&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%2Fe27l30nhq8478agn8vsx.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%2Fe27l30nhq8478agn8vsx.png" alt="env file"&gt;&lt;/a&gt;&lt;br&gt;
 After that create a plugins.js file in the config and add the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; module.exports = ({ env }) =&amp;gt; ({
  upload: {
    provider: "google-cloud-storage",
    providerOptions: {
      bucketName: "yourbucketnamehere",
      publicFiles: true,
      uniform: false,
      basePath: "",
      serviceAccount: env.json("GCP_SERVICE_ACCOUNT"),
    },
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it now we should be uploading files to the google bucket instead of a local file system. Now you can upload any media file and it will end up in your google bucket as:&lt;br&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%2F2z910s0ebcsj1uc27ruo.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%2F2z910s0ebcsj1uc27ruo.png" alt="Google cloud console"&gt;&lt;/a&gt;&lt;br&gt;
You can see it creates a bunch of files and folders when uploading files as it creates a different responsive version of the images that you upload. you can change this setting from within strapi admin as&lt;br&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%2Fxremjncae9f192m3fr1k.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%2Fxremjncae9f192m3fr1k.png" alt="Strapi Admin Dashboard"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;And that is it about using google Buckets to store media files in strapi. The process for uploading to other providers is also pretty similar. In another blog post, we'll create our landing page. If you have any problem with this setup and then let me know in the discussion.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Generate type information from gql graphql query using graphql code generator </title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Mon, 08 Nov 2021 11:40:21 +0000</pubDate>
      <link>https://dev.to/bishaln/generate-type-information-from-gql-graphql-query-using-graphql-generator-3n9k</link>
      <guid>https://dev.to/bishaln/generate-type-information-from-gql-graphql-query-using-graphql-generator-3n9k</guid>
      <description>&lt;p&gt;This is the third blog post on the series of blog post I am posting about strapi,nextjs, and tailwind. We are recreating my portfolio/blogpost page that along the way we'll learn the fundamentals of strapi,nextjs, and tailwind. You can check it out at &lt;a href="https://myportfolioandblog.vercel.app/" rel="noopener noreferrer"&gt;myportfolio&lt;/a&gt; If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series.&lt;/p&gt;

&lt;p&gt;In the last blog, we created the content-type that we would need in our application and also wrote a simple graphql query that would get us all the data required for our landing page. &lt;br&gt;
In this blog post, we are going to add a graphql code generator to generate type information from our gql graphql queries that we will be writing. Having type information is very helpful during development and saves a lot of time from not having to make simple type mistakes. &lt;/p&gt;

&lt;p&gt;So first thing first go to your nextjs project and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add -D @graphql-codegen/cli @graphql-codegen/gql-tag-operations-preset @graphql-codegen/typescript-operations 
or
npm i -D @graphql-codegen/cli @graphql-codegen/gql-tag-operations-preset @graphql-codegen/typescript-operations 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a new file in the project root and name it codegen.yaml and paste the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;overwrite: true
schema: 'http://localhost:1337/graphql'
documents:
  - 'src/**/*.ts'
  - '!src/gql/**/*'
generates:
  src/gql/:
    preset: gql-tag-operations-preset
    plugins:
      - typescript
      - typescript-operations

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

&lt;/div&gt;



&lt;p&gt;With this in place, let's issue the same query that we had in the last post that is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; query HomePage {
    homepage {
      Hero {
        title
        navlinks
        profile {
          url
        }
      }
      About {
        work
        blogs
        watch
        email
      }
      Project {
        title
        description
        tools
        image {
          url
        }
        url
        bg {
          url
        }
      }
      Contact {
        email
        insta
        linkedin
        twitter
        youtube
        title
      }
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make graphql request, we'll be using graphql-request so install it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; yarn add graphql-request graphql
 or 
 npm i graphql-request graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let create a folder src and move the pages and styles to src. also, create query and gql folder inside src folder&lt;br&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%2Fae4sjnijrk8di5yzla97.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%2Fae4sjnijrk8di5yzla97.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Now inside the queries folder add a file named homepage.ts and paste the following 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 { gql } from 'graphql-request';

export const exQuery = gql`
  query HomePage {
    homepage {
      Hero {
        title
        navlinks
        profile {
          url
        }
      }
      About {
        work
        blogs
        watch
        email
      }
      Project {
        title
        description
        tools
        image {
          url
        }
        url
        bg {
          url
        }
      }
      Contact {
        email
        insta
        linkedin
        twitter
        youtube
        title
      }
    }
  }
`;

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

&lt;/div&gt;



&lt;p&gt;To generate the type information we have to use the graphql codegen cli tool so let's add a script to package.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"gen": "yarn graphql-codegen --watch",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adding this run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This will run the graphql-codegen on watch mode and generate the type information from any exQuery that we've added. To confirm that we can see new files being added to the gql folder as&lt;br&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%2Firzstbw5ec94n3dbs5c2.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%2Firzstbw5ec94n3dbs5c2.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
With that now let's use this query inside our nextjs page&lt;br&gt;
So, replace the code in your index.ts with the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import type { NextPage } from 'next';
import { request } from 'graphql-request';
import { exQuery } from '../queries/homepage';
import { HomePageQuery } from '../gql/graphql';
import { useEffect, useState } from 'react';

const Home: NextPage = () =&amp;gt; {
  const [data, setData] = useState&amp;lt;HomePageQuery&amp;gt;();
  const query = async () =&amp;gt; {
    const data: HomePageQuery = await request(
      'http://localhost:1337/graphql',
      exQuery
    );
    setData(data);
  };
  useEffect(() =&amp;gt; {
    query();
  }, []);
  console.log(data?.homepage?.About?.blogs);
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p className='font-bold italic'&amp;gt;This is tailwindcss&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Home;

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

&lt;/div&gt;



&lt;p&gt;Now we get that nice autocompletion all thanks to the graphql code gen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is it for generating the type information from gql graphql query. In another blog post, we'll create our landing page.&lt;br&gt;
If you have any problem with this setup and then let me know in the discussion.&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Strapi content-type for simple portfolio and blog application</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Mon, 08 Nov 2021 10:24:05 +0000</pubDate>
      <link>https://dev.to/bishaln/strapi-content-type-for-simple-portfolio-and-blog-application-4ahc</link>
      <guid>https://dev.to/bishaln/strapi-content-type-for-simple-portfolio-and-blog-application-4ahc</guid>
      <description>&lt;p&gt;This is the second blog post on the series of a blogposts I am posting about strapi,nextjs, and tailwind. We are recreating my portfolio/blogpost page that along the way we'll learn the fundamentals of strapi,nextjs, and tailwind. You can check it out at &lt;a href="https://myportfolioandblog.vercel.app/" rel="noopener noreferrer"&gt;myportfolio&lt;/a&gt; If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series.&lt;/p&gt;

&lt;p&gt;In the last blog post we created bare-bones setup for strapi and nextjs with tailwindcss if you have not read the first blog post then go ahead &lt;a href="https://dev.to/bishaln/strapinextjs-and-tailwind-setup-50nk"&gt;https://dev.to/bishaln/strapinextjs-and-tailwind-setup-50nk&lt;/a&gt; &lt;br&gt;
In this blog post, we're going to look at the strapi's content-type and build our content-type for our portfolio/blog application.&lt;/p&gt;
&lt;h1&gt;
  
  
  Content-type builder
&lt;/h1&gt;

&lt;p&gt;It is a core plugin of strapi that allows us to manage the content-types and content-type defines the type of data that we want to use in our application. There are a few terms that we need to be aware of before going forward with this &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collection type - It is a content-type that can manage entries of the same content-type&lt;/li&gt;
&lt;li&gt;Single type - It is also a content-type that can only manage single entry&lt;/li&gt;
&lt;li&gt;Components are a data structure that can be used in multiple collection types and single types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've some regular fields that we can use in our content-type most of them are obvious so I will not bother explaining them&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;text-field&lt;/li&gt;
&lt;li&gt;rich-text&lt;/li&gt;
&lt;li&gt;number&lt;/li&gt;
&lt;li&gt;date&lt;/li&gt;
&lt;li&gt;boolean&lt;/li&gt;
&lt;li&gt;relation - used to establish relationships with another content-type&lt;/li&gt;
&lt;li&gt;email&lt;/li&gt;
&lt;li&gt;password&lt;/li&gt;
&lt;li&gt;enumeration&lt;/li&gt;
&lt;li&gt;media&lt;/li&gt;
&lt;li&gt;json&lt;/li&gt;
&lt;li&gt;uid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we have a decent understanding of strapi's content-type let's create the content type that we will need for our app.&lt;br&gt;
We'll have in total 4 content types as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Homepage - This is a single type that will contain all the data for our portfolio landing page&lt;/li&gt;
&lt;li&gt;Writer   - This is a collection type that will contain info about the writer of the blog posts&lt;/li&gt;
&lt;li&gt;Post   - This is a collection type &lt;/li&gt;
&lt;li&gt;Playlist - This is a collection type that will contain posts related to the playlist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's create them inside the strapi admin for that Inside your strapi project run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Go to &lt;a href="http://localhost:1337/admin" rel="noopener noreferrer"&gt;http://localhost:1337/admin&lt;/a&gt; and click the content-type builder in the plugins list&lt;/p&gt;

&lt;h1&gt;
  
  
  Homepage
&lt;/h1&gt;

&lt;p&gt;First let's create the homepage single type click on create a single type link and give it a name Homepage &lt;br&gt;
and Before adding any components or fields to our homepage single type I want you to visit the final app here &lt;a href="https://myportfolioandblog.vercel.app/" rel="noopener noreferrer"&gt;https://myportfolioandblog.vercel.app/&lt;/a&gt;&lt;br&gt;
If you see it carefully then it has 5 distinct sections&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hero&lt;/li&gt;
&lt;li&gt;about&lt;/li&gt;
&lt;li&gt;projects&lt;/li&gt;
&lt;li&gt;recent blogs&lt;/li&gt;
&lt;li&gt;contacts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;we'll create 4 components named hero, about, projects, and contacts. We will not create a recent blogs component for now;&lt;br&gt;
Inside the homepage single type click on add another field and select the component. Create a new component with the name Hero and a category with hero. Click on the configure selecting the single component.&lt;br&gt;
Now let's add some fields to this component &lt;br&gt;
title - text field&lt;br&gt;
navlinks - text field&lt;br&gt;
profile - media&lt;br&gt;
After adding this field the homepage single type looks something like this&lt;br&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%2F28hxkpum4x3f86dxbc7t.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%2F28hxkpum4x3f86dxbc7t.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Now let's add another component About follow the similar process and add these fields to the About component&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;work- text field select the long text radio&lt;/li&gt;
&lt;li&gt;blogs- same as work&lt;/li&gt;
&lt;li&gt;watch- same as work&lt;/li&gt;
&lt;li&gt;email- same as work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add another component Project follow the similar process but this time select the repeatable type instead of a single type so that we can add multiple projects and add these fields to the Project component&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title - text field for short text&lt;/li&gt;
&lt;li&gt;description - text field for long text&lt;/li&gt;
&lt;li&gt;url - text field for short text&lt;/li&gt;
&lt;li&gt;image - media &lt;/li&gt;
&lt;li&gt;bg - media &lt;/li&gt;
&lt;li&gt;tools - text field for short text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, let's add the Contact component follow the similar process this time make it a single type, and add these fields.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;email - text field for short text&lt;/li&gt;
&lt;li&gt;insta - same as email&lt;/li&gt;
&lt;li&gt;linkedin - same as email&lt;/li&gt;
&lt;li&gt;twitter - same as email&lt;/li&gt;
&lt;li&gt;youtube - same as email&lt;/li&gt;
&lt;li&gt;title - same as email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure to save the homepage. After all that we can now add real data to the homepage single type.&lt;br&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%2Frvt9tfhcsyiw8t2l1lnr.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%2Frvt9tfhcsyiw8t2l1lnr.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Go ahead and add some dummy data to the homepage if you want to&lt;br&gt;
Now we can focus on the other three collection types&lt;/p&gt;
&lt;h1&gt;
  
  
  Writer
&lt;/h1&gt;

&lt;p&gt;Go to content type builder and select create a new collection type and name it writer &lt;br&gt;
Add these fields to the writer content type and save it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name - text field for short text &lt;/li&gt;
&lt;li&gt;avatar - media for avatar&lt;/li&gt;
&lt;li&gt;bio - text field for long text&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Post
&lt;/h1&gt;

&lt;p&gt;Once again let's create another content type with the following fields and save it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title - text field for short text&lt;/li&gt;
&lt;li&gt;description - rich text&lt;/li&gt;
&lt;li&gt;topics - text field for short text&lt;/li&gt;
&lt;li&gt;slug - text field for short text make it unique to do that go to advanced tab and select unique&lt;/li&gt;
&lt;li&gt;writer - relation select writer content type and post has and belongs to one user&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Playlist
&lt;/h1&gt;

&lt;p&gt;Once again let's create another content type with the following fields and save it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title - text field for short text&lt;/li&gt;
&lt;li&gt;description - text field for long text&lt;/li&gt;
&lt;li&gt;slug - text field for short text make it unique to do that go to advanced tab and select unique&lt;/li&gt;
&lt;li&gt;posts - relation select posts content type and playlist has many posts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;we have to add some relation fields to posts and writers first let's add a playlist relation to posts&lt;br&gt;
as post has one playlist save it. &lt;br&gt;
Inside the writer, content-type add posts relation as a writer has many posts and save it&lt;/p&gt;

&lt;p&gt;Now go ahead and some dummy data to all the content-types so that we can query them;&lt;br&gt;
Before querying them we have to make all the content-types find and findone functions publicly available to do that goto&lt;br&gt;
settings -&amp;gt; user permission roles -&amp;gt; public  and check all the find and findones&lt;/p&gt;

&lt;p&gt;So now, to test lets query for all the data that you will need for the landing page;&lt;br&gt;
This query fetches all the data required for the landing page; cool isn't it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  homepage {
    Hero {
      title
      navlinks
      profile {url}
    }
    About {
      work
      blogs
      watch
      email
    }
    Project {
      title
      description
      tools
      image {url}
      url
      bg {url}
    }
    Contact {
      email
      insta
      linkedin
      twitter
      youtube
      title
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;So this is it for the content-type in strapi and we have added required content-types for our project. In the next blog post we will setup nextjs to make graphql requests and generate some type information from our queries. If you had any problem following along then let me know in the discussions&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Strapi,Nextjs and Tailwind setup</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Sun, 07 Nov 2021 13:16:14 +0000</pubDate>
      <link>https://dev.to/bishaln/strapinextjs-and-tailwind-setup-50nk</link>
      <guid>https://dev.to/bishaln/strapinextjs-and-tailwind-setup-50nk</guid>
      <description>&lt;p&gt;This is the first blog post on the series of a blog posts I will be posting about strapi,nextjs, and tailwind. We will be recreating my portfolio/blogpost website and along the way, we'll learn the fundamentals of strapi,nextjs and tailwind. You can check my &lt;a href="https://myportfolioandblog.vercel.app/" rel="noopener noreferrer"&gt;myportfolio&lt;/a&gt; If you know the basics of javascript and react then you should be good to follow this blog post and coming blog post on the series. I hope you'll get something out of this series.&lt;/p&gt;

&lt;p&gt;I am assuming that you have nodejs installed in your machine and I will be using yarn instead of npm you don't have to use yarn if you want then make sure to install yarn globally as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Strapi
&lt;/h1&gt;

&lt;p&gt;It is a headless content management system. Headless means it only serves data and not HTML and CSS. This is very powerful since we will just be getting the data that we care about and we can write the UI logic to display it nicely. We can use the same API endpoint in all the platforms to request the data be it web, mobile, or desktop.&lt;br&gt;
It comes with an admin UI that helps us to manage the content easily. Enough talk now let's see it in action;&lt;/p&gt;

&lt;p&gt;To create a brand new strapi app run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; yarn create strapi-app nameofyourapp
 or
 npx create-strapi-app my-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will ask for the installation type select custom and no for template choose sqlite as the development database we'll use postgres in production. &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%2F5qztxikwi9cn4418ufcz.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%2F5qztxikwi9cn4418ufcz.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
It will create a bunch of files for us we don't have to worry about any of the files created for now;&lt;br&gt;
So go ahead and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; yarn develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will first build the admin UI and spin up the server by default at &lt;a href="http://localhost:1337" rel="noopener noreferrer"&gt;http://localhost:1337&lt;/a&gt; &lt;br&gt;
 Now go ahead and open that link in a browser and for the first time, it will ask you for your credentials that we will use to login to the admin. After all that we should see an admin interface;&lt;br&gt;
 In strapi we first create the content-type think of it is a data structure or table schema. Now let's create a simple content-type say an Author with username, bio and image.&lt;/p&gt;

&lt;p&gt;Go to the content-types builder and click on create new collection type and Name your collection type Author and add some fields to it. Hit the save button it will restart the server and add Author as your new collection type alongside the users which is the default collection type used for authentication purposes.&lt;/p&gt;

&lt;p&gt;Now let's add some dummy author data so that we can query them with an HTTP request to do that go to the author collection data and click the add new authors button. Fill in the data save it and publish it then we should be able to see the newly added author in the author's collection type. &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%2F9hkxr0an9b2u57jvxjbr.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%2F9hkxr0an9b2u57jvxjbr.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
 To get this data first we have to make this content publicly available to do that let's go to&lt;br&gt;
 settings -&amp;gt; roles -&amp;gt; public and check the find and findone permissions and hit save.&lt;br&gt;
 Now let's make a simple get request to &lt;a href="http://localhost:1337/authors" rel="noopener noreferrer"&gt;http://localhost:1337/authors&lt;/a&gt; you should get something like this &lt;br&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%2Fzo10p2whqf40cwo1sdwr.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%2Fzo10p2whqf40cwo1sdwr.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
 Strapi by default processes the image that we upload to the media library but we can change the setting, for now, let's keep things simple. For this project, I want to make use of graphql instead of rest. If you have never made use of graphql then don't worry it is very simple. It provides several advantages that you can look up on the internet, for now, let's install a strapi plugin that will allow us to make graphql requests to our strapi server.&lt;/p&gt;

&lt;p&gt;Go ahead and run;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; yarn strapi install graphql
 or
 npm run strapi install graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After successful installation, we should be able to open up graphql playground at &lt;a href="http://localhost:1337/graphql" rel="noopener noreferrer"&gt;http://localhost:1337/graphql&lt;/a&gt;&lt;br&gt;
 In graphql for get request we use query and for others mutation. Let's write a simple query to get all the authors.&lt;br&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%2Fs6vzcaanfw8bmiqmenov.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%2Fs6vzcaanfw8bmiqmenov.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; query {
  authors {
    id
    created_at
    username
    bio
    avatar {
      url
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll talk more about the strapi content-types and relation in another blog post for now let's focus on setting up Nextjs and Tailwind.&lt;/p&gt;

&lt;p&gt;# Nextjs&lt;br&gt;
 It is a react framework that makes server-side rendering(SSR) and static site generation(SSG) super simple. In a normal create react app everything is computed client-side the user browser which is not good for performance as well as SEO. So we're going to make use of static site generation since the portfolio and blog site does not change that much.&lt;br&gt;
&lt;strong&gt;The difference between SSR and SSG is that in SSG nextjs pulls all the data during the build process and creates all pages that you have. When someone requests to access your page they will be served the pages which were built during the build process and without making any backend calls. This improves the performance of your website as well as decreases the load to your backend server whereas in SSR nextjs makes requests to your backend server for every request from the clients creates the page on the server and then serves it to the client.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's setup nextjs with typescript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn create next-app --typescript
or
npx create-next-app@latest --typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fdrhp5ts30u8jh9sksc67.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%2Fdrhp5ts30u8jh9sksc67.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will install all the dependencies and setup a simple page&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This starts the next server in dev goto &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  Tailwindcss
&lt;/h1&gt;

&lt;p&gt;It is a utility-first CSS framework that makes building UI simple and faster.&lt;br&gt;
Now let's add tailwindcss into the mix&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&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;Add this code snippet to the global CSS file&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;If you are using vs code then you can install the tailwindcss extension that will give you cool autocompletion so that you don't have to remember the class names;&lt;/p&gt;

&lt;p&gt;Now let's remove all the markup from the index.tsx file and test simple class from tailwind to make the text bold and italic;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import type { NextPage } from 'next';

const Home: NextPage = () =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p className='font-bold italic'&amp;gt;This is tailwindcss&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&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%2Fr57yla7pvjitf6ryq52m.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%2Fr57yla7pvjitf6ryq52m.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That is it for this blog post in the coming blog post we will discuss more about strapi content-types and add all the necessary content types for the portfolio/blog page Till then stay tuned if you have any questions about the current setup the let me know in the discussions&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Creating a CRUD Rest API using Nestjs</title>
      <dc:creator>Bishal Neupane</dc:creator>
      <pubDate>Wed, 13 Oct 2021 13:32:07 +0000</pubDate>
      <link>https://dev.to/bishaln/creating-a-crud-rest-api-using-nestjs-bnm</link>
      <guid>https://dev.to/bishaln/creating-a-crud-rest-api-using-nestjs-bnm</guid>
      <description>&lt;p&gt;&lt;strong&gt;Nestjs&lt;/strong&gt; is a nodejs framework that comes with lots of features out of the box unlike others such as expressjs, fastify which are minimal. Nestjs makes use of typescript by default which gives type safety to the project. Thus, keeping it safe from type errors which are quite common with javascript. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;In this tutorial&lt;/em&gt;, we are going to create a simple application that will help us create, read, update and delete notes about a topic.&lt;br&gt;
&lt;a href="https://github.com/BishalN/CRUD-REST_API"&gt;Complete Project Github Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First thing first make sure you have installed nodejs into &lt;br&gt;
your machine. &lt;code&gt;node -v&lt;/code&gt; if it gives back some version number then we are good to go otherwise make sure you download and install nodejs from here &lt;a href="https://nodejs.org/en/download/"&gt;nodejs download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now lets install nest cli;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g @nestjs/cli
          or
yarn global add @nestjs/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a brand new project using nest cli and I will name my project mynotes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nest new mynotes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create mynotes folder and a bunch of files that will get us up in running with nestjs. The main.ts file inside the src directory contains the main logic to start the nest application.&lt;br&gt;
Nestjs under the hood makes use of expressjs for HTTP implementation by default so we see expressjs like syntax to start the application.&lt;/p&gt;

&lt;p&gt;Before going through other files there are some term some terms that we need to know about nestjs;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Module&lt;/strong&gt; In nest we divide our project into several modules and these modules can be imported by other modules in the same project. It is also used to register imports, &lt;strong&gt;controllers&lt;/strong&gt; and &lt;strong&gt;providers&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controllers&lt;/strong&gt; It is the actual route handlers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Services&lt;/strong&gt; It contains the actual business logic that will be executed on the controllers &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository&lt;/strong&gt; It is used to define the data stores e.g Database entity i.e table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we know the basic terminologies, Let's go through all the other files created for us&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;app.module.ts&lt;/strong&gt; this file registers all the controllers and providers that are available in this module&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;app.controllers.ts&lt;/strong&gt; this file has an actual &lt;em&gt;Get&lt;/em&gt; route handler that returns hello world using the app service&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;app.services.ts&lt;/strong&gt; is injectable meaning we can use dependency injection that is how we are making use of getHello function on our &lt;em&gt;app.controllers.ts&lt;/em&gt; file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;app.controller.spec.ts&lt;/strong&gt; is a test file where we can write a unit test.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this tutorial, we will only use the &lt;strong&gt;app.module.ts&lt;/strong&gt;, &lt;strong&gt;app.controller.ts&lt;/strong&gt;, and &lt;strong&gt;main.ts&lt;/strong&gt; files. we will not make use of any other files so we can delete them.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jiG6dYh_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fvszrsfc50q4o3abbit.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jiG6dYh_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fvszrsfc50q4o3abbit.PNG" alt="Folder structure" width="204" height="368"&gt;&lt;/a&gt;&lt;br&gt;
Update the code in &lt;strong&gt;app.module.ts&lt;/strong&gt; and &lt;strong&gt;app.service.ts&lt;/strong&gt; to;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [],
  controllers: [AppController],
})
export class AppModule {}

//app.controller.ts
import { Controller, Get } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  getHello(): string {
    return 'hello world';
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's create the &lt;strong&gt;POST&lt;/strong&gt; endpoint to create the new notes with topic and description as a string for that we can use &lt;em&gt;&lt;a class="mentioned-user" href="https://dev.to/post"&gt;@post&lt;/a&gt;
&lt;/em&gt; and &lt;em&gt;@BODY&lt;/em&gt; decorator from the &lt;em&gt;@nest/common&lt;/em&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 { Body, Controller, Get, Post } from '@nestjs/common';

type note = {
  topic: string;
  description: string;
  id: number;
};

@Controller()
export class AppController {
  notes: note[] = [];

   @Post()
  createnote(@Body() { description, topic }: note) {
    const randomId = Math.floor(Math.random() * 999);
    const note = { description, topic, id: randomId };
    this.notes.push(note);
    return note;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will accept the post request at the root route and create a note and append it to the array. It returns the post created.&lt;/p&gt;

&lt;p&gt;Now let's create the &lt;strong&gt;GET&lt;/strong&gt; endpoint that will return all the notes created and another that will return the note by id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Get()
  getAllnote(): note[] {
    return this.notes;
  }

  @Get('/:id')
  getNoteById(@Param('id') id: number): note {
    const noteIndex = this.notes.findIndex((note) =&amp;gt; note.id === Number(id));
    return this.notes[noteIndex];
  }

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

&lt;/div&gt;



&lt;p&gt;Let's add the update functionality using a &lt;strong&gt;PUT&lt;/strong&gt; endpoint&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; @Put('/:id')
  updatenote(@Param('id') id: number, @Body() newNote: Partial&amp;lt;note&amp;gt;): note {
    const noteIndex = this.notes.findIndex((note) =&amp;gt; note.id === Number(id));
    this.notes[noteIndex] = { ...this.notes[noteIndex], ...newNote };
    return this.notes[noteIndex];
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, Let's implement the &lt;strong&gt;DELETE&lt;/strong&gt; method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; @Delete('/:id')
  deletenote(@Param('id') id: number): boolean {
    const noteIndex = this.notes.findIndex((note) =&amp;gt; note.id === Number(id));
    if (noteIndex === -1) return false;
    delete this.notes[noteIndex];
    return true;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used the POST method to create the new note, the GET method to get notes, the PUT method to update the note, and the Delete method to delete the notes. So, that is it about this CRUD tutorial.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>node</category>
      <category>nestjs</category>
    </item>
  </channel>
</rss>
