How to build a portfolio website with React & Tailwind CSS
Tags: webdev, tutorial, portfolio, react
Published: 2023-01-14 03:23:16

Every developer must have a portfolio website to showoff their skills and projects.

If you prefer video tutorial you can watch it here:

{% youtube i4l32fRFif0  %}



In this article I’ll show you how to do exactly that. 
We will build portfolio website with React.js and Tailwind CSS. 

You may ask It's just a landing page?
Why not build it with vanilla CSS and Html. 
The reason I choose React and Tailwind to build this project is because I’ll integrate a blog API into this project. I’ll share that in a future article. 

## Prerequisite:

To follow along you don’t need to be a pro at anything, all you need is just the fundamentals.

1. Basic understanding of vanilla CSS
2. Basic understanding of JavaScript.
3. Fundamental of React and Tailwind.

Now that you know what you need, let’s start building.


## Setup

To build the project first we need to setup a React.js and Tailwind CSS project. You can do that easily using the Tailwind docs. 
Follow [these](https://tailwindcss.com/docs/guides/create-react-app) instructions from tailwind docs to setup the project. 

[Setup React and Tailwind Project](https://tailwindcss.com/docs/guides/create-react-app)

I’ll wait for you to setup the project. 

You are done!

let’s move on to the next step.


## The Components

Before we start we need to know little about the structure of the project. 

Because it’s React we will be breaking down the websites into tiny components. 

We’ll have 6 components:

1. Header
2. Hero
3. About
4. Projects
5. Blog
6. Footer

Note: all these components will be inside the components folder under the **src** folder. And all the component will be imported in the **App.js** file. 

Like this:

```javascript
import "./App.css";
import Header from "./components/Header";
import Hero from "./components/Hero";
import About from "./components/About";
import Projects from "./components/Projects";
import Blog from "./components/Blog";
import Contact from "./components/Contact";
import Footer from "./components/Footer";

function App() {
  return (
    <>
      <Header />
      <Hero />
      <About />
      <Projects />
      <Blog />
      <Contact />
      <Footer />
    </>
  );
}

export default App;
```


### #1. Header

The have a responsive mobile menu with a toggle button, and a desktop menu.

We will use react useState hook to implement the toggle effect. And for the icons we’ll use the React Icons library.


```javascript

import React, { useState } from "react";
import { AiOutlineMenu, AiOutlineClose } from "react-icons/ai";

const Header = () => {
  const [toggle, setToggle] = useState(false);

  const handleToggle = () => setToggle(!toggle);

  return (
    <header className="flex justify-between px-5 py-2 bg-primary text-white fixed w-full z-10">
      <a href="/" className="logo text-2xl font-bold text-accent">
        Amrin
      </a>

      {/* Desktop Nav */}
      <nav className="hidden md:block">
        <ul className="flex">
          <li>
            <a href="/#about">About</a>
          </li>
          <li>
            <a href="/#projects">Projects</a>
          </li>
          <li>
            <a href="/#blog">Blog</a>
          </li>
          <li>
            <a href="/#contact">Contact</a>
          </li>
          <li>
            <a href="#resume -link" target="_blank" without rel="noreferrer">
              Resume
            </a>
          </li>
        </ul>
      </nav>

      {/* Mobile Nav */}
      <nav
        className={!toggle ? "mobile-nav left-[-100%]" : "mobile-nav left-0"}
      >
        <ul className="flex flex-col">
          <li>
            <a href="/#about">About</a>
          </li>
          <li>
            <a href="/#projects">Projects</a>
          </li>
          <li>
            <a href="/#blog">Blog</a>
          </li>
          <li>
            <a href="/#contact">Contact</a>
          </li>
          <li>
            <a href="/#resume">Resume</a>
          </li>
        </ul>
      </nav>

      {/* Toggle button */}
      <button onClick={handleToggle} className="block md:hidden">
        {!toggle ? <AiOutlineMenu size={30} /> : <AiOutlineClose size={30} />}
      </button>
    </header>
  );
};

export default Header;
```

Because we have a custom color pallet, I decided to create some utility classes for the colors.

```css
/* color */
.bg-primary {
    background: #0F172A;
}

.bg-secondery {
    background: #1E293B;
}

.bg-accent {
    background: #7477FF;
}

.text-accent {
    color: #7477FF;
} 
```

As we styled the mobile nav with tailwind, it was getting really messy and repetitive. So, I decided to extract the classes and put them on a custom class called .mobile-nav  on Style.css file, like this

```css
.mobile-nav {
    @apply block md:hidden fixed top-10 py-2 w-full h-full bg-gray-900 duration-500;
} 
```

Also to style the a tags inside nav, we used some custom css. Otherwise we would repeat ourselves a lot. 

```css
nav li a {
    @apply px-4 py-5 text-lg;
}

nav li a:hover {
    color: #7477FF;
}
```

Now that we are done with the nav let’s move on to the hero section. 

### #2. Hero

The hero consists of two sections, one is the hero-info and the other is hero-img.

I’ve used an illustration on the hero-img you can use your picture if you prefer.

```jsx
import React from "react";
import HeroImg from "../assets/hero-img.png";

import {
  AiOutlineTwitter,
  AiOutlineYoutube,
  AiOutlineFacebook,
} from "react-icons/ai";

const Hero = () => {
  return (
    <section className="bg-primary px-5 text-white py-32">
      <div className="container mx-auto grid md:grid-cols-2 items-center justify-center md:justify-between">
        <div className="hero-info pb-5 md:pb-0">
          <h1 className="text-4xl lg:text-6xl">
            Hi, <br />I am <span className="text-accent">a</span>mrin <br />
            Frontend Developer
          </h1>

          <p className="py-5">
            I am proficient in JavaScript, React.js and Tailwind CSS
          </p>

          <div className="flex py-5 ">
            <a
              href="https://twitter.com/CoderAmrin"
              className="pr-4 inline-block text-accent hover:text-white"
            >
              {" "}
              <AiOutlineTwitter size={40} />{" "}
            </a>
            <a
              href="https://www.youtube.com/@coderamrin"
              className="pr-4 inline-block text-accent hover:text-white"
            >
              {" "}
              <AiOutlineYoutube size={40} />{" "}
            </a>
            <a
              href="https://www.facebook.com/CoderAmrin/"
              className="pr-4 inline-block text-accent hover:text-white"
            >
              {" "}
              <AiOutlineFacebook size={40} />{" "}
            </a>
          </div>

          <a
            href="/#projects"
            className=" btn bg-accent  border-2 border-[#7477FF] text-white px-6 py-3 hover:bg-transparent"
          >
            See Projects
          </a>
        </div>

        <div className="hero-img">
          <img
            src={HeroImg}
            alt="coding illustration"
            className="lgw-[80%] ml-auto"
          />
        </div>
      </div>
    </section>
  );
};

export default Hero;
```

To style the hero title, we’ve used a custom font and added some custom styling. 

Note: you’ll need to add this font on the index.html of your project. It’s a free google font. 

```css
/* hero */
h1 {
    font-family: 'Pacifico', cursive;
    line-height: 1.5 !important;
}
```

### #3. About

The about section consists of two parts just like the hero section. 
First section will have all about you, what skills you have and what do you do. And the other section is about-img. It’s an illustration of a person coding.

Note: All the images are in the src/assets directory.  

```jsx
import React from "react";
import AboutImg from "../assets/about-img.png";

const About = () => {
  return (
    <section className="bg-secondery text-white px-5 py-32" id="about">
      <div className="container mx-auto grid md:grid-cols-2 items-center justify-center md:justify-between">
        <div className="about-info">
          <h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[180px] border-indigo-600 pb-2">
            About Me
          </h2>

          <p className="pb-5">
            Hi, My Name Is Rohima Akther everyone calls me Amrin. I am a
            Frontend Developer. I build beautifull websites with React and
            Tailwind CSS.
          </p>
          <p className="pb-5">
            I am proficient in Frontend skills like React.js, Redux, Redux Tool
            Kit, Axios, Tailwind CSS, SaSS, Css3 and many more.
          </p>

          <p>In backend I know Node.js, Express.js, MongoDB, and Mongoose</p>

          <p>
            In my spare time I create YouTube videos and write blogs on my Blog.
            Where I talk about programming theory and build various projects.
          </p>
        </div>

        <div className="about-img">
          <img
            src={AboutImg}
            alt="coding illustration"
            className="lgw-[80%] md:ml-auto"
          />
        </div>
      </div>
    </section>
  );
};

export default About;
```

To style this section we haven’t used any other custom css other than the color classes.

### #4. Project

The project section is a little bit complex. First we’ve got all the projects in an array, so that we don’t have to repeat ourselves. With this array of projects we now can easily map through and render the project item. 

```jsx
const projects = [
    {
      img: devlog,
      title: "devlog",
      desc: " A multi author blog. Built with Node.js, MongoDB, React, Redux and Tailwind CSS ",
      live: "https://devlogg.onrender.com/",
      code: "https://github.com/Coderamrin/devlog",
    },
    {
      img: uilogs,
      title: "uilogs",
      desc: "Free website template directory for SaaS and Degital Agency. Built with Bootstrap, JQuery and JavaScript",
      live: "https://uilogs.xyz/",
      code: "https://github.com/Coderamrin/html-templates",
    },
    {
      img: cssProjects,
      title: "css projects",
      desc: "Frontend Mentor challange directory, solved with vanilla CSS",
      live: "https://build-10-css-projects.netlify.app/",
      code: "https://github.com/Coderamrin/build-10-css-projects",
    },
    {
      img: getInspirred,
      title: "get Inspirred",
      desc: "Quote search app. Used Quotable API for the quotes and React, Redux on the frontend",
      live: "https://get-inspirred.netlify.app/",
      code: "https://github.com/Coderamrin/get-inspired",
    },
  ]; 
```

The rest of the product component is this.

```jsx
import React from "react";
import cssProjects from "../assets/cssprojects.png";
import devlog from "../assets/devlog.png";
import getInspirred from "../assets/get-inspirred.png";
import uilogs from "../assets/uilogs.png";

const Projects = () => {
  const projects = [...];

  return (
    <section className="bg-primary text-white px-5 py-32" id="projects">
      <div className="container mx-auto grid md:grid-cols-2 items-center md:justify-between">
        <div className="about-info mb-5">
          <h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[180px] border-indigo-600 pb-2">
            Projects
          </h2>

          <p className="pb-5">
            These are some of my best projects. I have built these with React,
            MERN and vanilla CSS. Check them out.
          </p>
        </div>

        <div className="about-img"></div>
      </div>

      <div className="projects container mx-auto grid md:grid-cols-3 gap-10">
        {projects.map((project, i) => {
          return (
            <div className="relative" key={i}>
              <img src={project.img} alt={project.title} />
              <div className="flex absolute left-0 right-0 top-[13px] bottom-0 mx-auto w-[90%] h-[90%]  bg-primary  opacity-0 duration-500 justify-center flex-col hover:opacity-100 ">
                <p className="py-5 text-center font-bold px-2 text-white">
                  {project.desc}
                </p>

                <div className="mx-auto">
                  <a
                    href={project.live}
                    className="px-5 py-2 bg-blue-500 hover:bg-blue-600 mr-5 font-bold"
                  >
                    Live
                  </a>
                  <a
                    href={project.code}
                    className="px-5 py-2 bg-blue-700 hover:bg-blue-800 font-bold"
                  >
                    Code
                  </a>
                </div>
              </div>
            </div>
          );
        })}
      </div>
    </section>
  );
};

export default Projects;
```

### #5. Blog

Now is the blog section. It almost like the projects section.

An array of blog items to map through and render the items. 

All the other things are the same as the projects component. 

```jsx
import React from "react";

const Blog = () => {
  const post = [
    {
      img: "https://res.cloudinary.com/practicaldev/image/fetch/s--AuZFJnr6--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8okx5rxzuh5fojibsy3.png",
      title: "How to build a counter app with JavaScript",
      url: "https://dev.to/coderamrin/how-to-build-a-counter-app-with-javascript-439p",
    },
    {
      img: "https://res.cloudinary.com/practicaldev/image/fetch/s--FsJZ6lhI--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gv7y2de8kalk9l0820ag.jpg",
      title: "JavaScript Ultimate Guide 02: The DOM",
      url: "https://dev.to/coderamrin/javascript-ultimate-guide-02-the-dom-3ho9",
    },
  ];

  return (
    <section className="bg-primary text-white px-5 py-32" id="blog">
      <div className="container mx-auto grid md:grid-cols-2 items-center md:justify-between">
        <div className="about-info mb-5">
          <h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[100px] border-indigo-600 pb-2">
            Blogs
          </h2>

          <p className="pb-5">Some of my best blogs.</p>
        </div>

        <div></div>
      </div>

      <div className="projects container mx-auto grid md:grid-cols-2 gap-10">
        {post.map((item) => {
          return (
            <div>
              <img src={item.img} alt={item.title} />
              <h3 className="py-5 text-2xl">{item.title}</h3>
              <a
                href={item.url}
                className=" btn bg-accent  border-2 border-[#7477FF] text-white px-6 py-3 hover:bg-transparent"
              >
                Read More
              </a>
            </div>
          );
        })}
      </div>
    </section>
  );
};

export default Blog; 
```

### #6. Contact & Footer

Finally the contact section and the Footer section. 

These sections are just some texts on the center of the div. No, fancy design. 

### #Contact

```jsx
import React from "react";

const Contact = () => {
  return (
    <section className="bg-secondery px-5 py-32" id="contact">
      <div className="text-center md:w-[60%] mx-auto text-white">
        <h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[200px] mx-auto border-indigo-600 pb-2">
          Contact Me
        </h2>
        <p>
          I am currently open for a fulltime Frontend Developer role. If you
          want to discuss about that feel free to email me or call me.
        </p>

        <p className="py-2">
          <span className="font-bold">Email:</span> coderamrin@gmail.com
        </p>
        <p className="py-2">
          <span className="font-bold">Phone:</span> +88 01624-890723
        </p>
      </div>
    </section>
  );
};

export default Contact;
```

### #Footer

```jsx
import React from "react";

const Footer = () => {
  return <div className="py-4 text-center bg-primary text-white "> &copy; 2023 coderamrin all right reserved</div>;
};

export default Footer;
```

### Resources
**Live:** https://amrin.onrender.com/
**Source Code:** https://github.com/Coderamrin/portfolio

### Conclusion

Now you have a portfolio. You can deploy it and show off your projects. 

If you want you can add a blog to your portfolio and showoff your skills. 

I’ll add dev api on this portfolio, if you want to see do the same follow me to notified when I post the article. 

If you want to connect with me, you can find me at on [Twitter](https://twitter.com/CoderAmrin) and [YouTube](https://www.youtube.com/@coderamrin/). 

Thanks for reading to the end. 

See you on a future article.