Getting Started with React: Creating Your Own Blog App - Part 2

Mastering Navigation and Routing in React: Building a Blog App Step-by-Step

ยท

14 min read

Getting Started with React: Creating Your Own Blog App - Part 2

Introduction

In this article on the React series, we will learn how to navigate between pages using react-router. This article covers basic navigation from one page to another using react-router. In our next blog post, we will in-depth into react-router and explore navigating between pages programmatically or using dynamic URLs.

We will also examine the file architecture of this Blog app and discuss why file architecture plays an important role when it comes to building any app. I won't cover the HTML and CSS design aspects, but if necessary, I'll explain the JSX structure if it becomes too complex for you.

In our previous blog post, we learned...

In our latest blog post, we covered how to create a React project using VITE and explained the various files generated during the installation of a React project. If you haven't read our previous blog post, I recommend doing so. Additionally, I discussed the React code that comes with the installation of a React project file.

If you are already familiar with installing React or using VITE to install React, feel free to skip directly to this blog post. I encourage you to read our previous blog, as you might learn something new. Please don't hesitate to share your feedback, as it helps me improve and motivates me to write more engaging content.

Prerequisites

  • Familiar with HTML & CSS

  • Proficiency in Vanilla JavaScript

  • Any Code Editor

  • Nodejs Installed on the system

  • Read my previous blog posts to understand where we are in this series.

Explaining the File Structure in Our Project

In general, a file structure refers to the organization of information on your computer. In the context of programming, the Broad Institute of MIT and Harvard defines a file structure as code organized with repeatability in mind. This arrangement makes it simpler for anyone who has access to your project to navigate its files.

A key advantage of file structures is that they make locating and accessing files easier. This ability to locate files enables developers to work more efficiently. File structures in programming allow developers to know where files are, when to use specific code, and find related results. Not only do file structures enhance productivity, but they also improve code consistency and shareability.

Standard File Conventions

  • node_modules: This folder includes libraries and dependencies for JS packages used by the npm package manager.

  • public: This folder serves as the root directory for the public assets of your application. It contains files that are publicly accessible to the users and It's essential to understand that the files in the public folder are not processed by any build tool

  • src (source): The files in this folder are meant to build and develop the project. This is where the original source files are located.

  • assets: These files are static content like images, video, audio, and fonts.

  • components: The files in this folder are meant to be reusable components like buttons, header, footer, cards, etc. Reusable components refer to modular and self-contained pieces of code that can be used in multiple parts of an application.

  • css: The files in this folder are meant to be CSS files to design our components, pages, or any other place where we need CSS.

  • pages: The files in this folder are meant to be our react pages which we write and develop for our react project.

Markdown Files

  • README.md: This file contains information about the other files in a directory. It is usually a simple plain text file called README, Read Me, READ.ME, README.TXT, or README.1ST.

  • LICENSE.md: This file shows you any rights given to you regarding the project. Alternative names include LICENSE or LICENSE.txt

Every developer, team, or organization follows different file structures to work with. For our Blog app, we are going to use this simple file structure, which I use quite often for any project. As the project scales, we change our file structure, making it more organized, consistent, and shareable, which helps us be more productive and allows other team members to work seamlessly.

This is merely an overview; countless file structures become more detailed and adaptable based on the programming language you are using for your project. Allocate some time to investigate structures related to your preferred language.

Now, let's write some code and install a few packages using NPM for our React Blog App.

Install React Bootstrap Package

To design our app, we are using Bootstrap CSS framework but we will use React Bootstrap specifically for rebuilding for React.

React Bootstrap is a popular library that combines the power of React with the styling and components of Bootstrap, a widely used front-end framework.

To install the package, open up your VSCode terminal and navigate to your project directory which is for me is Project/blogapp-react, and use npm to install the react-bootstrap bootstrap package:

npm install react-bootstrap bootstrap

Adding FontAwesome Icons in our App

We're not going to use many icons, perhaps just two or three in our app. I don't want to spend too much time installing the FontAwesome package. Instead, I'll directly use the FontAwesome CDN link and paste it into our index.html file.

If you wish to use other attractive icons, you can do so. React supports a wide range of icon libraries. We will be using FontAwesome 4.7 icons. All you need to do is:

Copy the link below and paste it into our index.html file:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- Font Awesome 4.7 Link ๐Ÿ‘‡ -->
<link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css"
      integrity="sha512-5A8nwdMOWrSz20fDsjczgUidUBR8liPYU+WymTZP1lmY9G6Oc7HlZv156XqnsgNUzTyMefFTcsFH/tnJE/+xBg=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    />
<!-- Font Awesome 4.7 Link ๐Ÿ‘† -->
    <title>Blog App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

Adding Google Fonts in our App

We have added Bootstrap and FontAwesome Icons, and now we are going to incorporate Google Fonts. Google Fonts offers a wide range of beautiful fonts that can be used anywhere, free of charge. This means there is no need to purchase a license to use them.

Visit the URL https://fonts.google.com/, choose your desired font, and copy the HTML link into your index.html file. Additionally, you must add a CSS style to the global CSS file, which is index.css.

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css"
      integrity="sha512-5A8nwdMOWrSz20fDsjczgUidUBR8liPYU+WymTZP1lmY9G6Oc7HlZv156XqnsgNUzTyMefFTcsFH/tnJE/+xBg=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    />
<!-- Google Fonts Link ๐Ÿ‘‡ -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;700&display=swap"
      rel="stylesheet"
    />
<!-- Google Fonts Link ๐Ÿ‘† -->
    <title>Blog App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

index.css

body {
  font-family: "Poppins", sans-serif;
}

Install react-router-dom Package

Before installing this package, you might wonder what the react-router-dom package is and why we need it. Doesn't React support routing using its own routing system?

This type of question might come to your mind and that's a good sign because It shows that you are actively engaging with the material, thinking critically, and seeking a deeper understanding.

Let me explain why we use this react-router-dom package.

React itself doesn't have built-in routing capabilities. While React is excellent at managing the UI components and rendering, it doesn't handle page navigation and URL routing out of the box. This is where the react-router-dom package comes into play.

react-router-dom is a popular and widely-used package that provides a set of components and utilities for implementing client-side routing in React applications. It allows you to create multiple "pages" or "views" within a single-page application (SPA) and manage the navigation between them, all without requiring a full page refresh.

To install react-router-dom the package ๐Ÿ‘‡

Open up your VSCode terminal and navigate to your project directory which is for me is Project/blogapp-react, and use npm to install the react-router-dom package:

npm install react-router-dom

Good!! You install the routing package to our react app. Here are the few reasons why we are using react-router-dom package...

  • Declarative Routing: react-router-dom allows you to declare routes and their corresponding components in a declarative way, making it easy to define the UI layout and flow of your application.

  • Component-Based Navigation: The package leverages React's component-based architecture to handle navigation. Each route is associated with a React component, making it intuitive to manage and organize different parts of your app.

  • History Management: react-router-dom uses browser history APIs to manage the history of page navigation. This enables smooth transitions between pages without full-page reloads.

  • Dynamic Routing: You can set up dynamic routes with parameters, allowing you to create more flexible and dynamic page structures.

  • Nested Routing: react-router-dom supports nested routes, making it easy to create complex UI layouts and manage the navigation flow in deeply nested components.

  • Route Guarding: The package provides tools for guarding routes, which means you can control access to certain routes based on conditions, like user authentication.

There are many alternatives for react-router-dom package but to make this article and our app make it simple we will use this package.

Headers and Footers

We have installed the react-router-dom routing package; now let's put it into action and implement it in our app.

Let's create header.jsx and footer.jsx files in the components folder. Why? Because we plan to use these components on every page, and React is primarily known for its reusable components.

Additionally, I am creating separate CSS files for the Header and Footer because I prefer a modular architecture where we separate each section based on components. This approach makes it easy to make changes in one file, and it will automatically reflect in all other files where these components are imported.

I won't be delving into HTML & CSS. You can bypass the design aspect and directly copy and paste the code from here or from GitHub as well.

footer.jsx

import "../css/footer.css";

function Footer() {
  return (
    <div className="footer-main fixed-bottom">
      <h4>Blogim!</h4>
      <p>&#169; Copyright {new Date().getFullYear()} All Rights Reserved</p>
    </div>
  );
}

export default Footer;

What is className ?

In React, className is a special attribute used to define the CSS class names for an HTML element rendered by a React component. It is analogous to the class attribute in regular HTML. Since class is a reserved keyword in JavaScript, React uses className to set the class names dynamically for the components it renders.

The className attribute accepts a string containing one or more CSS class names, separated by spaces. These class names define the styles that will be applied to the component when it is rendered in the DOM.

For example ๐Ÿ‘‡

<div className="my-component red-text">
      This is my component with red text.
</div>

The resulting HTML will look like this:

<div class="my-component red-text">
  This is my component with red text.
</div>

In our CSS, we can define styles for the classes like this:

.my-component {
  width:100%;
}

.red-text {
  color: red;
}

Using className allows you to apply styles dynamically to React components, making it easy to manage the appearance of your UI based on different states or conditions. It is a common and essential attribute when working with React and applying CSS styles to components.

The only reason for using className instead of class is that class is a reserved keyword in JavaScript. Since React utilizes JSX, which is an extension of JavaScript, it is necessary to use the className attribute instead of class.

header.jsx

import { Link } from "react-router-dom";

//Local Imports
import "../css/header.css";

function Header() {
  return (
    <div className="header-main d-flex align-items-center justify-content-between">
      <div className="app-logo">
        <h4>Blogim!</h4>
      </div>
      <div className="navbar-menu-items">
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/blog">Add blog</Link>
          </li>
          <li>
            <Link to="/profile">Profile</Link>
          </li>
        </ul>
      </div>
    </div>
  );
}

export default Header;
  • Header component is responsible for rendering a navigation header bar for a web application. It uses the Link component from react-router-dom to create clickable links that enable client-side routing without full page reloads.

  • Imports the Link component from the react-router-dom library. This component is used to create links that navigate between different pages or routes in the application.

  • The Link component from react-router-dom is used to create clickable links that handle client-side navigation within the React application.

  • The to prop is used to specify the path/route the link should navigate to. For example, <Link to="/">Home</Link> means clicking on "Home" will navigate to the root path ("/") of the application, while <Link to="/blog">Add blog</Link> will navigate to the "/blog" path.

  • When a Link component is clicked, the React Router takes care of updating the browser's URL and rendering the corresponding component without causing a full page to reload.

Now, we need to setup react-router-dom package in our app.

main.jsx

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App.jsx";
import "bootstrap/dist/css/bootstrap.min.css";
import "./index.css";

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

In this code, the points to note and understand are:

<React.StrictMode>

  • The React.StrictMode component is a special component provided by React. It is used to enable a set of strict development mode checks for the application.

  • It does not render any visible UI elements itself but rather affects its children's components. It helps highlight potential issues and deprecations during development, promoting best practices and optimizations.

  • When you wrap your components with React.StrictMode, it checks for unsafe practices and provides helpful warnings in the development console.

<BrowserRouter>

  • First, Import BrowserRouter from react-router-dom.

  • The BrowserRouter component is part of the react-router-dom library, which provides routing capabilities for single-page applications in React.

  • It is used here to enable client-side routing, which allows the application to handle different URLs and navigate to different pages without full page reloads.

  • With BrowserRouter, we can define different routes in the application and control which components are displayed based on the URL.

Create Home, Blog and Profile Page

Here, we have created the homepage, blog page, and profile page within the pages folder.

Within each of these pages, for now, we will simply add a div containing the file name.

homepage.jsx

function Homepage() {
  return <div className="center-page">Home page</div>;
}

export default Homepage;

profile.jsx

function Profile() {
  return <div className="center-page">Profile Page</div>;
}

export default Profile;

blog.jsx

function Blog() {
  return <div className="center-page">Blog Page</div>;
}

export default Blog;

App.jsx

import React from "react";
import { Routes, Route } from "react-router-dom";

//Local Imports
import Header from "./components/header";
import Footer from "./components/footer";
import Homepage from "./pages/homepage";
import Blog from "./pages/blog";
import Profile from "./pages/profile";
import NoPageFound from "./pages/no_page_found";
import "./App.css";

function App() {
  return (
    <React.Fragment>
      <Header />
      <Routes>
        <Route path="/" element={<Homepage />} />
        <Route path="/blog" element={<Blog />} />
        <Route path="/profile" element={<Profile />} />
        <Route path="*" element={<NoPageFound />} />
      </Routes>
      <Footer />
    </React.Fragment>
  );
}

export default App;

In this code, the points to note and understand are:

  • imports necessary modules from React and React Router, including React, Routes, and Route

  • Also imports various components used in the application: Header, Footer, Homepage, Blog, Profile, and NoPageFound.

  • The <React.Fragment> (or the shorthand syntax <> ... </>) is used to wrap multiple elements in JSX without adding an extra DOM element to the rendered output. In our case, it's used to group the components <Header />, <Routes>, and <Footer />.

  • The <Header /> and <Footer /> components represent the top and bottom sections of the application, creating a consistent layout for the whole app.

  • The <Routes> component is a container for all the route definitions.

  • Inside the <Routes> component, we have multiple <Route> components. Each <Route> represents a specific URL path and its corresponding component (Homepage, Blog, Profile, or NoPageFound).

  • The path prop of the <Route> component specifies the URL path for which it should be rendered. For example, <Route path="/blog" element={<Blog />} /> means that when the URL path is "/blog", the Blog component will be rendered.

  • The element prop of the <Route> component specifies the component that should be rendered when the URL path matches the path prop.

  • You might be thinking what is no_page_found page? the <Route> with path="*" and the corresponding element={<NoPageFound />} is a special route that is used as a fallback when none of the previously defined routes matches the current URL. It acts as a catch-all route for any unknown or undefined paths, commonly referred to as a "404 Not Found" page

NOTE: You need to copy CSS from the git repository or you can write your own CSS.

Run your APP

Simply run the following command in your terminal:

npm run dev

Hopefully, you didn't encounter any errors. Once your app runs successfully, it should appear like this:

Now give yourself a pat on the back, as you've just implemented a Routing in our React app.

So, that's it for this blog.

What's Next?

In the next blog, we will start implementing the addition of blogs and displaying a list of them. During this process, we will learn about form handling, rendering lists of blogs, and using a WYSIWYG (What You See Is What You Get) editor.

WYSIWYG editor provides a user-friendly interface that enables users to create and format content without requiring any coding knowledge. This makes it accessible to a wider audience, including those who are not technically inclined.

In our next blog, we will take a deeper dive into the code.

Conclusion

In conclusion, this article covered the basics of setting up navigation and routing in a React application using react-router-dom. We learned about the importance of file structure, installed the necessary packages, and implemented a simple header and footer.

Thank you for reading my article. Please Follow Me, Feel free to comment and share your suggestions or thoughts.

Also, Follow me on Twitter or Linkedin I share Cloud, System Design, Code, and many more tech stuff ๐Ÿ˜Š

Resources

Did you find this article valuable?

Support Pradhuman Blog by becoming a sponsor. Any amount is appreciated!

ย