Dev.to clone built with Next.js & Chakra UI

Let’s clone dev.to with the actual dev.to api to get the posts and lists.

Overview

This application is built with the following technologies:

Typescript
Nextjs
Chakra UI
SWR
Dev.to api

Live demo: https://dev-to-clone-ma.vercel.app
Githu…


This content originally appeared on DEV Community and was authored by Muhammad Ahmad

Let's clone dev.to with the actual dev.to api to get the posts and lists.

Overview

This application is built with the following technologies:

Live demo: https://dev-to-clone-ma.vercel.app
Github repo: https://github.com/MA-Ahmad/dev.to-clone

Breaking down the layout of Dev.to

  • Top navbar
  • Left sidebar
  • Posts section
  • Right sidebar

I'll discuss some components code here otherwise this article will become very long.

1. Setup the Project

Create a Next.js app

yarn create next-app --typescript

Install chakra-ui

yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4

2. Start coding

Top navbar

const Navbar = () => {
  return (
    <Box
      py="2"
      boxShadow="sm"
      border="0 solid #e5e7eb"
      position="fixed"
      top="0"
      bg="#fff"
      width="100%"
      zIndex="1"
    >
      <Container>
        <HStack spacing={4}>
          <Image src="/assets/images/logo.svg" />
          <Input
            maxW="26rem"
            placeholder="Search..."
            borderColor="#b5bdc4"
            borderRadius="5px"
            d={{ base: "none", md: "block" }}
          />
          <Spacer />
          <HStack spacing={3}>
            <Button
              color="#fff"
              borderRadius="4px"
              bg="#3b49df"
              _hover={{ bg: "#323ebe" }}
            >
              Create a post
            </Button>
            <IconButton>
              <Image src="/assets/images/notification.svg" />
            </IconButton>
            <IconButton>
              <Image src="/assets/images/bell.svg" />
            </IconButton>
            <Avatar
              size={"sm"}
              src={"https://avatars2.githubusercontent.com/u/37842853?v=4"}
            />
          </HStack>
        </HStack>
      </Container>
    </Box>
  );
};

Navbar

Left sidebar

Links section

const Links = () => {
  return (
    <Box as="nav">
      <LinkButton>
        <Image src="/assets/images/sidebar/home.svg" mr="3" />
        Home
      </LinkButton>
      <LinkButton>
        <Image src="/assets/images/sidebar/reading.svg" mr="3" />
        Reading List
      </LinkButton>
      <LinkButton>
        <Image src="/assets/images/sidebar/tag.svg" mr="3" />
        Tags
      </LinkButton>
      <LinkButton>
        <Text fontWeight="normal" color="#4d5760" ml="2.3rem">
          More...
        </Text>
      </LinkButton>
    </Box>
  );
};

Tags section

const Tags = () => {
  return (
    <Box mt="6">
      <Flex pl="2" py="4">
        <Heading as="h3" fontSize="1rem">
          My Tags
        </Heading>
        <Spacer />
        <Image src="/assets/settings.svg" />
      </Flex>
      <Box maxH="50vh" overflowY="auto">
        <TagList>
          {[
            "Nextjs",
            "react",
            "javascript",
            "ruby",
            "ruby on rails",
            "css",
            "beginners",
            "html",
            "typescript"
          ]}
        </TagList>
      </Box>
    </Box>
  );
};

left-sidebar

Posts section

End point for showing feed https://dev.to/stories/feed
Post card component

<Box
      mt="3"
      as="article"
      bg="white"
      borderRadius="md"
      overflow="hidden"
      border="1px solid #08090a1a"
    >
      {headerImage ? <Image src={headerImage} /> : ""}
      <Grid templateColumns="max-content 1fr" gap={2} p={4}>
        <Image src={userProfile} w="8" borderRadius="full" />

        <Box>
          <VStack align="flex-start" spacing={0}>
            <Text color="#4d5760" fontSize="14px" fontWeight="500">
              {username}
            </Text>
            <Text color="#4d5760" fontSize="12px">
              {publishedDate}
            </Text>
          </VStack>
          <Heading fontSize={headerImage ? "30px" : "24px"} mt="3">
            <Link
              href={postLink}
              _hover={{ color: "#323ebe", textDecoration: "none" }}
              isExternal
            >
              {title}
            </Link>
          </Heading>
          <HStack mt="3" fontSize="14px" color="#64707d">
            {tagList.map((tag, idx) => (
              <Text as={Link} key={idx}>
                #{tag}
              </Text>
            ))}
          </HStack>
          <HStack mt={3}>
            <Button
              leftIcon={<Image src="/assets/images/like.svg" />}
              ml={-2}
              bg="transparent"
              padding="6px 8px"
              height="auto"
              fontWeight="normal"
              fontSize="14px"
              lineHeight="1.2"
              borderRadius="4px"
              _hover={{ bg: "#f6f6f6" }}
            >
              {reactionCount} reactions
            </Button>
            <Button
              leftIcon={<Image src="/assets/images/comment.svg" />}
              bg="transparent"
              padding="6px 8px"
              height="auto"
              fontWeight="normal"
              fontSize="14px"
              lineHeight="1.2"
              borderRadius="4px"
              _hover={{ bg: "#f6f6f6" }}
            >
              {commentCount} comments
            </Button>
            <Spacer />
            <Text fontSize="12px">{readingTime} min read</Text>
            <Button
              bg="#d2d6db"
              padding="8px 12px"
              height="auto"
              fontWeight="normal"
              fontSize="14px"
              _hover={{ bg: "#b5bdc4" }}
            >
              Save
            </Button>
          </HStack>
        </Box>
      </Grid>
    </Box>

posts skeleton
posts

Right sidebar

End point for showing list https://dev.to/api/listings

const List = () => {
  const { data, error } = useSWR("https://dev.to/api/listings", fetcher);

  if (error) return <Box>failed to load</Box>;
  if (!data)
    return (
      <Box as="section" bg="white" borderRadius="md" border="1px solid #E2E4E6" width="100%">
        <ListHeading />
        {[1, 2, 3, 4, 5].map(id => {
          return (
            <Box borderBottom="1px solid #E2E4E6" width="100%" p="3">
              <Skeleton height="15vh" borderRadius="5px" width="100%" />
            </Box>
          );
        })}
      </Box>
    );

  return (
    <Box as="section" bg="white" borderRadius="md" border="1px solid #E2E4E6">
      <ListHeading />
      {data.slice(0, 7).map(list => (
        <ListBox title={list.title} category={list.category} slug={list.slug} />
      ))}
    </Box>
  );
}

Listing

Responsiveness

responsiveness
responsiveness


This content originally appeared on DEV Community and was authored by Muhammad Ahmad


Print Share Comment Cite Upload Translate Updates
APA

Muhammad Ahmad | Sciencx (2021-06-26T14:24:05+00:00) Dev.to clone built with Next.js & Chakra UI. Retrieved from https://www.scien.cx/2021/06/26/dev-to-clone-built-with-next-js-chakra-ui/

MLA
" » Dev.to clone built with Next.js & Chakra UI." Muhammad Ahmad | Sciencx - Saturday June 26, 2021, https://www.scien.cx/2021/06/26/dev-to-clone-built-with-next-js-chakra-ui/
HARVARD
Muhammad Ahmad | Sciencx Saturday June 26, 2021 » Dev.to clone built with Next.js & Chakra UI., viewed ,<https://www.scien.cx/2021/06/26/dev-to-clone-built-with-next-js-chakra-ui/>
VANCOUVER
Muhammad Ahmad | Sciencx - » Dev.to clone built with Next.js & Chakra UI. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/06/26/dev-to-clone-built-with-next-js-chakra-ui/
CHICAGO
" » Dev.to clone built with Next.js & Chakra UI." Muhammad Ahmad | Sciencx - Accessed . https://www.scien.cx/2021/06/26/dev-to-clone-built-with-next-js-chakra-ui/
IEEE
" » Dev.to clone built with Next.js & Chakra UI." Muhammad Ahmad | Sciencx [Online]. Available: https://www.scien.cx/2021/06/26/dev-to-clone-built-with-next-js-chakra-ui/. [Accessed: ]
rf:citation
» Dev.to clone built with Next.js & Chakra UI | Muhammad Ahmad | Sciencx | https://www.scien.cx/2021/06/26/dev-to-clone-built-with-next-js-chakra-ui/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.