Getting Started with React: Creating Your Own Blog App - Part 2
Mastering Navigation and Routing in React: Building a Blog App Step-by-Step
Table of contents
- Introduction
- In our previous blog post, we learned...
- Prerequisites
- Explaining the File Structure in Our Project
- Install React Bootstrap Package
- Adding FontAwesome Icons in our App
- Adding Google Fonts in our App
- Install react-router-dom Package
- Headers and Footers
- Create Home, Blog and Profile Page
- What's Next?
- Conclusion
- Resources
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 thepublic
folder are not processed by any build toolsrc (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 calledREADME
, Read Me,READ.ME
,README.TXT
, orREADME.1ST
.LICENSE.md:
This file shows you any rights given to you regarding the project. Alternative names includeLICENSE
orLICENSE.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>© 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 fromreact-router-dom
to create clickable links that enable client-side routing without full page reloads.Imports the
Link
component from thereact-router-dom
library. This component is used to create links that navigate between different pages or routes in the application.The
Link
component fromreact-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 thereact-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
, andRoute
Also imports various components used in the application:
Header
,Footer
,Homepage
,Blog
,Profile
, andNoPageFound.
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
, orNoPageFound
).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
", theBlog
component will be rendered.The
element
prop of the<Route>
component specifies the component that should be rendered when the URL path matches thepath
prop.You might be thinking what is
no_page_found
page? the<Route>
withpath="*"
and the correspondingelement={<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
https://github.com/asenseofpradhyu/blogapp-react/tree/blog_2
Part 1: Blog Link for This Series :- https://pradhuman.hashnode.dev/getting-started-with-react-creating-your-own-blog-app-part-1