Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 26, 2021 02:24 pm GMT

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:

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


Original Link: https://dev.to/m_ahmad/dev-to-clone-built-with-next-js-chakra-ui-ccl

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To