Build a landing page using React, Chakra UI and Typescript
Published: 2022-08-24 18:15:00

-   Tools Used: Chakra UI, React, Typescript
-   Time Saved: 1 week -> 45 mins
-   [View Demo](https://chakra-ui-landing-page-react.vercel.app/)
-   [Source code on Github](https://github.com/bdcorps/chakra-ui-landing-page-react)

This guide walks through how to create a landing page for a launched SaaS app using React and Typescript.

Introduction
------------

[Chakra UI](https://chakra-ui.com/) is a UI component library that is very easy to use, has accessibility out of the box, and most importantly, looks incredible.

In this guide, we will be creating a landing page for a SaaS product with:

1.  Hero section - Hooks the reader. Details what the product is about
2.  Demo video - What the product looks like in action
3.  Company logos - Trust builder that shows other companies are liking the product already
4.  Features - Top 3 ways the product helps users
5.  Highlights - Secondary features that are nice to have
6.  Pricing
7.  FAQ
8.  CTA - Remind readers to sign up after they have read all about the product
9.  Footer


Step 1 - Set up React project
-----------------------------

```bash
npm create vite@latest saasbase-chakraui-landing-page -- --template react-ts

cd saasbase-chakraui-landing-page
npm install
npm run dev
```


Step 2 - Set up Chakra UI
-------------------------

Chakra UI is a fantastic UI kit that comes with easy-to-use Front-end components that also look good.

```bash
npm i @chakra-ui/react @emotion/react @emotion/styled framer-motion @chakra-ui/icons
```



We can set it up by wrapping our entire application with the `ChakraUIProvider`.

Install the Inter font with:

```bash
npm i @fontsource/inter
```


Edit `src/main.tsx`

```javascript
import { ChakraProvider, extendTheme } from "@chakra-ui/react";
import React from "react";
import ReactDOM from "react-dom/client";
import { App } from "./App";

const theme = extendTheme({
  colors: {
    brand: {
      50: "#f0e4ff",
      100: "#cbb2ff",
      200: "#a480ff",
      300: "#7a4dff",
      400: "#641bfe",
      500: "#5a01e5",
      600: "#5200b3",
      700: "#430081",
      800: "#2d004f",
      900: "#14001f",
    },
  },
  fonts: {
    heading: `'Inter', sans-serif`,
    body: `'Inter', sans-serif`,
  },
});

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <ChakraProvider theme={theme}>
      <App />
    </ChakraProvider>
  </React.StrictMode>
);
```


Step 3 - Create the Hero section
--------------------------------

The hero section of your landing page is the most important above-the-fold item you can have. The title and the description should hook the reader in to learn more about your offering within 4-5 secs.

Our Hero section will have a title, description, and a strong CTA to get the readers salivating. A trust builder that shows that others are already using your product goes a long way.

![Hero Section](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-11.33.29-AM.png)

Create a new file `src/components/HeroSection.tsx` :

```javascript
import {
  Button,
  Center,
  Container,
  Heading,
  Text,
  VStack,
} from "@chakra-ui/react";
import { FunctionComponent } from "react";

interface HeroSectionProps {}

export const HeroSection: FunctionComponent<HeroSectionProps> = () => {
  return (
    <Container maxW="container.lg">
      <Center p={4} minHeight="70vh">
        <VStack>
          <Container maxW="container.md" textAlign="center">
            <Heading size="2xl" mb={4} color="gray.700">
              You don't have to chase your clients around to get paid
            </Heading>

            <Text fontSize="xl" color="gray.500">
              Freelancers use Biller to accept payments and send invoices to
              clients with a single click
            </Text>

            <Button
              mt={8}
              colorScheme="brand"
              onClick={() => {
                window.open("https://launchman.cc", "_blank");
              }}
            >
              I need this for $10/month →
            </Button>

            <Text my={2} fontSize="sm" color="gray.500">
              102+ builders have signed up in the last 30 days
            </Text>
          </Container>
        </VStack>
      </Center>
    </Container>
  );
};
```


Update the `src/App.tsx` with:

```javascript
import { Box } from "@chakra-ui/react";
import { HeroSection } from "./components/HeroSection";

export const App = () => {
  return (
    <Box bg="gray.50">
      <HeroSection />
    </Box>
  );
};
```


We will continue to add new components to this page as we build them out.

Step 3 - Add Header
-------------------

Now that we have some content in the page, we can add a header/navigation bar. This will show the name of our product, quick links for navigating to parts of the page, and a link to my Twitter.


[Download the SVG image of the Twitter Icon from here](https://launchman-space.nyc3.digitaloceanspaces.com/twitter-logo.svg) and place it in the `public` folder. Any file in this folder is served as is. This is where you want to keep all the static assets your site uses.

Let's start by creating a new component that will create a responsive header bar. Call it `src/components/Header.tsx` :

```javascript
import { HamburgerIcon } from '@chakra-ui/icons'
import {
  Box,
  chakra,
  Container,
  Drawer,
  DrawerBody,
  DrawerCloseButton,
  DrawerContent,
  DrawerHeader,
  DrawerOverlay,
  Flex,
  Heading,
  IconButton,
  Image,
  Link,
  LinkBox,
  LinkOverlay,
  Spacer,
  Stack,
  useDisclosure,
} from '@chakra-ui/react'

const navLinks = [
  { name: 'Home', link: '/' },
  { name: 'Features', link: '#features' },
  { name: 'Pricing', link: '#pricing' },
]

const DesktopSidebarContents = ({ name }: any) => {
  return (
    <Container maxW={['full', 'container.lg']} p={0}>
      <Stack
        justify="space-between"
        p={[0, 4]}
        w="full"
        direction={['column', 'row']}
      >
        <Box display={{ base: 'none', md: 'flex' }}>
          <Heading fontSize="xl">{name}</Heading>
        </Box>
        <Spacer />
        <Stack
          align="flex-start"
          spacing={[4, 10]}
          direction={['column', 'row']}
        >
          {navLinks.map((navLink: any, i: number) => {
            return (
              <Link
                href={navLink.link}
                key={`navlink_${i}`}
                fontWeight={500}
                variant="ghost"
              >
                {navLink.name}
              </Link>
            )
          })}
        </Stack>
        <Spacer />
        <LinkBox>
          <LinkOverlay href={`https://twitter.com/thisissukh_`} isExternal>
            <Image src="twitter.svg"></Image>
          </LinkOverlay>
        </LinkBox>
      </Stack>
    </Container>
  )
}
const MobileSidebar = ({ name }: any) => {
  const { isOpen, onOpen, onClose } = useDisclosure()

  return (
    <>
      <Flex w="full" align="center">
        <Heading fontSize="xl">{name}</Heading>
        <Spacer />
        <IconButton
          aria-label="Search database"
          icon={<HamburgerIcon />}
          onClick={onOpen}
        />
        <Drawer isOpen={isOpen} placement="right" onClose={onClose} size="xs">
          <DrawerOverlay />
          <DrawerContent bg="gray.50">
            <DrawerCloseButton />
            <DrawerHeader>{name}</DrawerHeader>

            <DrawerBody>
              <DesktopSidebarContents />
            </DrawerBody>
          </DrawerContent>
        </Drawer>
      </Flex>
    </>
  )
}

interface SidebarProps {
  name: string
}

const Sidebar = ({ name }: SidebarProps) => {
  return (
    <chakra.header id="header">
      <Box display={{ base: 'flex', md: 'none' }} p={4}>
        <MobileSidebar name={name} />
      </Box>

      <Box display={{ base: 'none', md: 'flex' }} bg="gray.50">
        <DesktopSidebarContents name={name} />
      </Box>
    </chakra.header>
  )
}

interface HeaderProps {
  name: string
}

export const Header = ({ name }: HeaderProps) => {
  return (
    <Box w="full">
      <Sidebar name={name} />
    </Box>
  )
}
```


Add a `src/components/Layout.tsx`

```javascript
import { Box, VStack } from "@chakra-ui/react";
import { FunctionComponent } from "react";
import { Header } from "./Header";

interface LayoutProps {
  children: React.ReactNode;
}

export const Layout: FunctionComponent<LayoutProps> = ({
  children,
}: LayoutProps) => {
  return (
    <Box bg="gray.50">
      <VStack spacing={10} w="full" align="center">
        <Header name="Biller" />
        {children}
      </VStack>
    </Box>
  );
};
```

Update the `src/App.tsx` with:

```javascript
import { Box } from "@chakra-ui/react";
import { HeroSection } from "./components/HeroSection";
import { Layout } from "./components/Layout";

export const App = () => {
  return (
    <Layout>
      <Box bg="gray.50">
        <HeroSection />
      </Box>
    </Layout>
  );
};
```


Step 4 - Add a demo video
-------------------------

A demo video lets the reader know what to expect when they do signup for your product.

Record an MP4 video of your product and place it in the `public` folder as `video.mp4` . Next.js serves everything from the `public` folder as is.

If you don't have one, [here's a sample video](https://launchman-space.nyc3.digitaloceanspaces.com/biller-hero-2.webm) and a [sample poster image](https://launchman-space.nyc3.digitaloceanspaces.com/biller-hero-2.png) you can use.

![Add demo video](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-11.34.03-AM.png)

We can also add a `poster` option in the `video` tag that shows a static image if the video isn't yet loaded. Using a static frame of the video as the poster works well.

Update `src/App.tsx` with:

```javascript
import { Box } from "@chakra-ui/react";
import { HeroSection } from "./components/HeroSection";
import { Layout } from "./components/Layout";

export const App = () => {
  return (
    <Layout>
      <Box bg="gray.50">
        <HeroSection />
      	<Container maxW="container.xl">
          <Center p={[0, 10]}>
            <video playsInline autoPlay muted poster="/image.png" loop>
              <source src="/video.mp4" type="video/mp4" />
            </video>
          </Center>
		</Container>
      </Box>
    </Layout>
  );
};
```



Step 5 - Add social proof with client logos
-------------------------------------------

Now that the reader knows what the offering is, you can answer their next logical question - who else is using it?

Adding logos of customers at recognizable companies using your product will build trust with the reader.

Download the SVG logos for [Microsoft](https://launchman-space.nyc3.digitaloceanspaces.com/microsoft-logo.svg) and [Adobe](https://launchman-space.nyc3.digitaloceanspaces.com/adobe-logo.svg) and place them in `public` folder just like before.

![Add Social Proof](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-1.42.07-PM.png)

Update the `src/App.tsx` with:

```javascript
import {
  Box,
  Center,
  Container,
  Wrap,
  WrapItem,
  Text,
  Image,
} from "@chakra-ui/react";
// ...

export const App = () => {
  return (
    <Layout>
      <Box bg="gray.50">
       // ...

<Container maxW="container.2xl" centerContent py={[20]}>
            <Text color="gray.600" fontSize="lg">
              Used by teams worldwide
            </Text>

            <Wrap
              spacing={[10, 20]}
              mt={8}
              align="center"
              justify="center"
              w="full"
            >
              <WrapItem>
                <Image src="microsoft-logo.svg" alt="Microsoft logo" />
              </WrapItem>

              <WrapItem>
                <Image src="adobe-logo.svg" alt="Adobe logo" />
              </WrapItem>

              <WrapItem>
                <Image src="microsoft-logo.svg" alt="Microsoft logo" />
              </WrapItem>

              <WrapItem>
                <Image src="adobe-logo.svg" alt="Adobe logo" />
              </WrapItem>
            </Wrap>
          </Container>
      </Box>
    </Layout>
  );
};
```



Step 6 - List features
----------------------

The features section is where you can flaunt the top 3 ways your product will help a potential user. I like to be as direct as possible.

![Features](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-11.34.32-AM.png)

Create a new file called `src/components/Feature.tsx`

```javascript
import {
  Box,
  Button,
  Center,
  Container,
  Stack,
  Text,
  VStack,
  Image,
} from "@chakra-ui/react";
import { FunctionComponent } from "react";

interface FeatureProps {
  title: string;
  description: string;
  image: string;
  reverse?: boolean;
}

export const Feature: FunctionComponent<FeatureProps> = ({
  title,
  description,
  image,
  reverse,
}: FeatureProps) => {
  const rowDirection = reverse ? "row-reverse" : "row";
  return (
    <Center w="full" minH={[null, "90vh"]}>
      <Container maxW="container.xl" rounded="lg">
        <Stack
          spacing={[4, 16]}
          alignItems="center"
          direction={["column", null, rowDirection]}
          w="full"
          h="full"
        >
          <Box rounded="lg">
            <Image
              src={image}
              width={684}
              height={433}
              alt={`Feature: ${title}`}
            />
          </Box>

          <VStack maxW={500} spacing={4} align={["center", "flex-start"]}>
            <Box>
              <Text fontSize="3xl" fontWeight={600} align={["center", "left"]}>
                {title}
              </Text>
            </Box>

            <Text fontSize="md" color="gray.500" textAlign={["center", "left"]}>
              {description}
            </Text>

            <Button
              colorScheme="brand"
              variant="link"
              textAlign={["center", "left"]}
            >
              Learn more →
            </Button>
          </VStack>
        </Stack>
      </Container>
    </Center>
  );
};
```



Add to `src/App.tsx`

```javascript
import { Feature } from "./components/Feature";
// ...

interface FeatureType {
  title: string
  description: string
  image: string
}

const features: FeatureType[] = [
  {
    title: "Detailed Analytics",
    description:
      "No more spending hours writing formulas in Excel to figure out how much you're making. We surface important metrics to keep your business going strong.",
    image:
      "https://launchman-space.nyc3.digitaloceanspaces.com/chakra-ui-landing-page-feature-1.png",
  },
  {
    title: "Track your clients",
    description:
      "Know when and how your projects are going so you can stay on top of delivery dates.",
    image:
      "https://launchman-space.nyc3.digitaloceanspaces.com/chakra-ui-landing-page-feature-2.png",
  },
  {
    title: "Manage projects",
    description:
      "You don't have to hunt your email inbox to find that one conversation. Every task, project, and client information is just a click away.",
    image:
      "https://launchman-space.nyc3.digitaloceanspaces.com/chakra-ui-landing-page-feature-3.png",
  },
];

export const App = () => {
  return (
    <Layout>
      <Box bg="gray.50">
        // ...
      <VStack
          backgroundColor="white"
          w="full"
          id="features"
          spacing={16}
          py={[16, 0]}
        >
          {features.map(
            ({ title, description, image }: FeatureType, i: number) => {
              return (
                <Feature
                  key={`feature_${i}`}
                  title={title}
                  description={description}
                  image={image}
                  reverse={i % 2 === 1}
                />
              )
            }
          )}
        </VStack>
      </Box>
    </Layout>
  );
};
```



Step 7 - Add highlights
-----------------------

Add a new file called `Highlight.tsx`

```javascript
import {
  Box,
  Center,
  Container,
  Wrap,
  WrapItem,
  Text,
  Image,
  VStack,
  SimpleGrid,
} from "@chakra-ui/react";
// ...

export interface HighlightType {
  icon: string
  title: string
  description: string
}

const highlights: HighlightType[] = [
      {
        icon: '✨',
        title: 'No-code',
        description:
          "We are No-Code friendly. There is no coding required to get started. Launchman connects with Airtable and lets you generate a new page per row. It's just that easy!",
      },
      {
        icon: '🎉',
        title: 'Make Google happy',
        description:
          "We render all our pages server-side; when Google's robots come to index your site, the page does not have to wait for JS to be fetched. This helps you get ranked higher.",
      },
      {
        icon: '😃',
        title: 'Rapid experimenting',
        description:
          "You don't have to wait hours to update your hard-coded landing pages. Figure out what resonates with your customers the most and update the copy in seconds",
      },
      {
        icon: '🔌',
        title: 'Rapid experimenting',
        description:
          "You don't have to wait hours to update your hard-coded landing pages. Figure out what resonates with your customers the most and update the copy in seconds",
      },
    ]

export const App = () => {
  return (
    <Box bg="gray.50">
      // ...
     <Container maxW="container.md" centerContent py={[8, 28]}>
          <SimpleGrid spacingX={10} spacingY={20} minChildWidth="300px">
            {highlights.map(({ title, description, icon }, i: number) => (
              <Box p={4} rounded="md" key={`highlight_${i}`}>
                <Text fontSize="4xl">{icon}</Text>

                <Text fontWeight={500}>{title}</Text>

                <Text color="gray.500" mt={4}>
                  {description}
                </Text>
              </Box>
            ))}
          </SimpleGrid>
        </Container>
    </Box>
  );
};

```


![Highlights](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-11.34.56-AM.png)

Step 8 - Add the Pricing section
--------------------------------

Here you can add a pricing section to your page by clearly showing what features are available at what price point. Offering an Annual subscription can be beneficial for both yourself and the customer.

![Pricing](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-11.35.16-AM.png)

Create a new component in `src/components/PricingSection.tsx`

```javascript
import { CheckCircleIcon } from '@chakra-ui/icons'
import {
  Box,
  Button,
  ButtonGroup,
  HStack,
  List,
  ListIcon,
  ListItem,
  SimpleGrid,
  Text,
  VStack,
} from '@chakra-ui/react'
import { FunctionComponent, useState } from 'react'

interface PricingBoxProps {
  pro: boolean
  name: string
  isBilledAnnually: boolean
}

export const PricingBox: FunctionComponent<PricingBoxProps> = ({
  pro,
  name,
  isBilledAnnually,
}: PricingBoxProps) => {
  return (
    <Box
      boxShadow="sm"
      p={6}
      rounded="lg"
      bg={pro ? 'white' : 'white'}
      borderColor={pro ? 'brand.500' : 'gray.200'}
      backgroundColor={pro ? 'brand.50' : 'white'}
      borderWidth={2}
    >
      <VStack spacing={3} align="flex-start">
        <Text fontWeight={600} casing="uppercase" fontSize="sm">
          {name}
        </Text>
        <Box w="full">
          {isBilledAnnually ? (
            <Text fontSize="3xl" fontWeight="medium">
              $89
            </Text>
          ) : (
            <Text fontSize="3xl" fontWeight="medium">
              $99
            </Text>
          )}
          <Text fontSize="sm">per month per site</Text>
        </Box>

        <Text>Unlock key features and higher usage limits</Text>
        <VStack>
          <Button size="sm" colorScheme="brand">
            Free 14-day trial →
          </Button>
        </VStack>

        <VStack pt={8} spacing={4} align="flex-start">
          <Text fontWeight="medium">Everything in Basic, plus:</Text>
          <List spacing={3}>
            <ListItem>
              <HStack align="flex-start" spacing={1}>
                <ListIcon as={CheckCircleIcon} color="brand.500" mt={1} />
                <Text>
                  Lorem ipsum dolor sit amet, consectetur adipisicing elit
                </Text>
              </HStack>
            </ListItem>
          </List>
        </VStack>
      </VStack>
    </Box>
  )
}

interface PricingSectionProps {}

export const PricingSection: FunctionComponent<PricingSectionProps> = () => {
  const [isBilledAnnually, setIsBilledAnnually] = useState<boolean>(true)
  return (
    <VStack spacing={10} align="center">
      <ButtonGroup isAttached>
        <Button
          onClick={() => {
            setIsBilledAnnually(true)
          }}
          colorScheme={isBilledAnnually ? 'brand' : 'gray'}
        >
          Annually (-10%)
        </Button>

        <Button
          onClick={() => {
            setIsBilledAnnually(false)
          }}
          colorScheme={isBilledAnnually ? 'gray' : 'brand'}
        >
          Monthly
        </Button>
      </ButtonGroup>

      <SimpleGrid columns={[1, null, 3]} spacing={10}>
        <PricingBox
          pro={false}
          name="Starter"
          isBilledAnnually={isBilledAnnually}
        />

        <PricingBox
          pro={true}
          name="Creator"
          isBilledAnnually={isBilledAnnually}
        />

        <PricingBox
          pro={false}
          name="Enterprise"
          isBilledAnnually={isBilledAnnually}
        />
      </SimpleGrid>
    </VStack>
  )
}
```


Add the component to `src/App.tsx`

```javascript
import { PricingSection } from "./components/PricingSection";
// ...

export const App = () => {
  return (
    <Box bg="gray.50">
      // ...
        <Container py={28} maxW="container.lg" w="full" id="pricing">
          <PricingSection />
        </Container>
    </Box>
  );
};

```


Step 9 - Add an FAQ section
---------------------------

Handle objections your potential customer might have in the FAQ section.

![FAQ](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-11.35.41-AM.png)

Add a component called `src/components/FAQSection.tsx` :

```javascript
import {
  Accordion,
  AccordionButton,
  AccordionIcon,
  AccordionItem,
  AccordionPanel,
  Box,
} from '@chakra-ui/react'

export interface FAQType {
  q: string
  a: string
}

interface FAQSectionProps {
  items: FAQType[]
}

export const FAQSection = ({ items }: FAQSectionProps) => {
  return (
    <Box borderRadius="lg" w="full" p={4}>
      <Accordion>
        {items.map((item: any, i: number) => {
          return (
            <AccordionItem key={`faq_${i}`}>
              <h2>
                <AccordionButton>
                  <Box flex="1" textAlign="left">
                    {item.q}
                  </Box>
                  <AccordionIcon />
                </AccordionButton>
              </h2>

              <AccordionPanel pb={4}>{item.a}</AccordionPanel>
            </AccordionItem>
          )
        })}
      </Accordion>
    </Box>
  )
}
```


Update `src/App.tsx` :

```javascript
import { FAQSection, FAQType } from "./components/FAQSection";
// ...

const faqs: FAQType[] = [
      {
        q: 'How many clients can I bring on?',
        a: 'You can bring on 3 clients with the Free plan. Upgrade to Pro for additional seats.',
      },
      {
        q: 'Can I connect it to my CRM?',
        a: 'Yes! We support Notion and PipeDrive currently.',
      },
      {
        q: 'Do you support international payments?',
        a: 'Yes - payments can be made from and to any country.',
      },
      {
        q: 'Who can I connect to for support?',
        a: 'Email me at sukh@saasbase.dev',
      },
    ]

export const App = () => {
  return (
    <Layout>
      <Box bg="gray.50">
        // ...
        <Container py={28} maxW="container.md">
          <Box w="full">
            <VStack spacing={10} w="full">
              <Text fontWeight={500} fontSize="2xl" align="center">
                Frequently asked questions
              </Text>
              <FAQSection items={faqs} />
            </VStack>
          </Box>
        </Container>
      </Box>
    </Layout>
  );
};
```


Step 10 - Add CTA
-----------------

Add a final CTA to make it easy for the reader to subscribe now that they know everything about the product.

![CTA](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-11.35.56-AM.png)

Create a new component called `src/components/CTA.tsx` :

```javascript
import { Button, Container, Text, VStack } from '@chakra-ui/react'
import React, { FunctionComponent } from 'react'
import { CTAType } from '../types'

interface CTAProps {
  heading: string
  cta: CTAType
}

export const CTA: FunctionComponent<CTAProps> = ({
  heading,
  cta,
}: CTAProps) => {
  return (
    <Container maxW="container.lg" py={16}>
      <VStack
        spacing={6}
        backgroundColor="brand.500"
        rounded="xl"
        p={6}
        backgroundImage="https://uploads-ssl.webflow.com/60c29c0c0d66236222bfa9b4/60c29c0d0d66230460bfa9e2_Pattern%20Shape.svg"
      >
        <VStack spacing={4} maxW="md">
          <Text fontWeight={600} fontSize="3xl" align="center" color="white">
            {heading}
          </Text>
        </VStack>

        <Button
          size="lg"
          color="brand.500"
          backgroundColor="white"
          onClick={() => {}}
        >
          {cta.name}
        </Button>
      </VStack>
    </Container>
  )
}

```


Update `src/App.tsx` :

```javascript
import { CTA } from '../components/CTA'
// ...

export const App = () => {
  return (
    <Layout>
      <Box bg="gray.50">
        // ...
      <CTA
          heading={`Get started with Biller  today!`}
          cta={{ name: 'I want this!', link: '#' }}
        />
      </Box>
    </Layout>
  );
};
```


Step 11 - Add Footer
--------------------

Add a footer with a social link to Twitter.

Update `src/App.tsx` :

```javascript
import {
  Container,
  Box,
  Center,
  Text,
  Wrap,
  WrapItem,
  Image,
  VStack,
  SimpleGrid,
  Flex,
  LinkBox,
  LinkOverlay,
  Spacer,
} from "@chakra-ui/react";
// ...

export const App = () => {
  return (
    <Layout>
      <Box bg="gray.50">
       // ...
		<Container maxW="container.lg">
          <Flex py={6}>
            <Box>
              <Text>© 2022 Biller</Text>

              <Text>Made by Sukh</Text>
            </Box>
            <Spacer />

            <LinkBox>
              <LinkOverlay href="https://twitter.com/@thisissukh_" isExternal>
                <Image src="twitter.svg" alt="Twitter logo"></Image>
              </LinkOverlay>
            </LinkBox>
          </Flex>
        </Container>
      </Box>
    </Layout>
  );
};
```


![Footer](https://www.saasbase.dev/content/images/2022/08/Screen-Shot-2022-08-14-at-1.51.00-PM.png)

Step 12 - Add SEO
-----------------

React Helmet is a great package that helps us optimize on-page SEO. Install it by:

```bash
npm i react-helmet
npm i --save-dev @types/react-helmet
```


Update `src/App.tsx` :

```javascript
import {Helmet} from "react-helmet";

export const App = () => {
  return (
    <Layout>
      <Helmet>
        <meta charSet="utf-8" />
        <title>Biller | Get paid faster</title>
      </Helmet>
      <Box bg="gray.50">
         // ...
      </Box>
    </Layout>
  );
};
```


Step 13 - Deploy on Vercel
--------------------------

Vercel is the smoothest deployment platform I've ever used.

Deploy your React/Vite project by:

1.  Upload source code to Github
2.  Select `Vite` as the Framework Preset

![Vercel Deploy](https://www.saasbase.dev/content/images/2022/08/image.png)

3\. Hit Deploy

That's it - you have a brand new landing page ready to go with Chakra UI!