A React.js template with Parcel.js and Bootstrap 5
Tags: javascript, beginners, tutorial, react
Published: 2024-01-08 15:22:39

This guide provides a step-by-step tutorial of a structured starting point for a React project using the Parcel bundler and Bootstrap 5 for styling. The initial setup is inspired by Bob Ziroll's tutorial on [freecodecamp](https://www.freecodecamp.org/news/how-to-up-a-react-app-with-parcel/).

## Preview

![webpage preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/033it4kjkfc66a29bx3r.png)


## Features
- Pre-configured project with a ready-to-use file structure
- Utilizes React for dynamic and interactive components
- Parcel bundling for efficient management and minimised configuration
- Bootstrap 5 styles and components integrated

This template facilitates a quick and straightforward start for your website.


## Structure
```
.
.
(dist)
(node_modules)
├── src/                  # Source code
│   ├── index.html        # HTML entry point
│   ├── index.js          # JavaScript entry point
│   ├── App.js            # Main React component
│   └── components/       # React components
│       ├── NavBar.js     # Navigation bar component
│       ├── Content.js    # Main content component
│       └── Footer.js     # Footer component
├── .gitignore            # Git ignore file
├── package.json          # npm package file
├── package-lock.json     # npm package lock file
└── README.md             # Project README

```




---

## GitHub repository:
{% embed https://github.com/LucasSuL/my-react-parcel-bootstrap-template/ %}

### Note:
If you are not familiar with React, npm and Bootstrap as I did before, I recommend following this tutorial step by step to build your project folder. Alternatively, you can directly download the repository and follow the instructions in GitHub:

![GitHub instruction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/580dbsiqcenjy98z6ssl.png)



---

## Getting Started

To run the project locally, follow these steps:

### 1. Create a new folder for your project
Just create a new folder in which you want to place your project. Ensure you have Node.js and npm installed on your machine. You can download them from [nodejs.org](https://nodejs.org/).


### 2. Create your `package.json` file
If you are using VSCode, you can press `` Ctrl + ` ``(Windows) to open the terminal, navigate to the new project's root folder using `cd` (or you can simply drag the project folder into the code area of your VSCode) and then run:
```
npm init -y
```

> 
This command initializes a new Node.js project and generates a `package.json` file with default values without requiring user input. The `-y` flag stands for "yes" and it automatically accepts all default configurations, making the initialization process faster by skipping the interactive setup.

### 3. Install Parcel, React, and ReactDOM
Then, we can use node package management tool (npm) with code `npm install [replace this with what you need]` to install `Node.js` packages or dependencies.
* Still, in terminal, execute the following commands to install Parcel:
```
npm install --save-dev parcel-bundler
```

> 
`--save-dev` is used to specify that the package being installed is a development dependency. It means that this package is necessary for development purposes but not for the production environment.

After a successful installation, you should see the latest `parcel-bundler` in the `devDependencies` section of your `package.json`.

* Install Bootstrap:
```
npm install bootstrap
```
* Install React and ReactDOM:
```
npm install react react-dom
```


> `ReactDOM` is a package in the React library that takes your React components and renders them into the DOM.

Untill now, you should have added `node_modules` `dist` `.cache` and `package-lock.json` to your project folder.

Alternatively, for a quicker setup, you can include the [CDN link](https://www.jsdelivr.com/package/npm/bootstrap) and include it in your `<head>` section of `index.html`.

### 4. Add necessary configuration
In the `package.json` file, within the `"scripts"` section, include the following `"start"` script:
     
```json
"scripts": {
  "start": "parcel index.html --open"
}
```

> 
This allows you to run commands like `npm start` to actually let Parcel initiate your project and open a new tab of your default browser. If you want to skip opening the browser, you can omit `--open`. Additionally, consider adding `"build": "parcel build src/index.html"` for building your project, although it's optional for now.


### 5. Create the file structure for your project!

You don't need to manually create your project file structure as listed above on your own (although I highly recommend doing it manually during the learning phase to deepen your understanding). Instead, here is a quicker way: 
At the project root, execute the following commands to generate a complete folder structure with the necessary files. Take note of the variations between different systems:

For OS:

```
mkdir -p src/components
touch src/index.html src/index.js src/App.js src/components/NavBar.js src/components/Content.js src/components/Footer.js
```

For Windows:
```
mkdir -p src/components
New-Item -ItemType file src/index.html, src/index.js, src/App.js, src/components/NavBar.js, src/components/Content.js, src/components/Footer.js

```

### 6. index.html
* Open `index.html`, press ' ! ' and then 'Enter' to generate an Emmet HTML template:
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
```

* Inside the `<head>` element, include Fontawesome:
```html
<script defer src="https://use.fontawesome.com/releases/v6.1.2/js/all.js"></script>
```
> 
This is code to load the [Font Awesome](https://fontawesome.com/icons/) icon library. The script tag should be placed in the `<head>` section of the HTML file. Including the `defer` attribute ensures that the script is executed after the document has been parsed, preventing it from blocking the page load and thereby improving performance.

* Inside the `<body>` element, create a `<div >`with id of "root":
```html
<div id="root"></div>
```
* Link to JavaScript file by adding:
```html
<script src="./index.js"></script>
```

> 
Using a `<div>` with an id of "root" is a common practice in React. Another beneficial step is placing the `<script>` tag just before the closing `</body>` tag, this achieves a similar effect to adding `defer` attribute.

### 7. index.js
* Import React and ReactDOM at the top:
```javascript
import React from "react"
import ReactDOM from "react-dom/client"
```

> 
`react-dom/client` is a lighter-weight version of `react-dom` for building a single-page application (SPA). For study purposes, this won't make a noticeable difference.

* Create root
Use the `createRoot` method from `ReactDOM` to retrieve the DOM element with the ID 'root' in `index.html` and create a new root entry point for a React tree.
```javascript
const root = ReactDOM.createRoot(document.getElementById('root'));
```

> 
Again, this is a conventional operation. Please note that this is part of the Concurrent Mode feature introduced in React 18, which won't be a problem if you follow my tutorial.

* Test your React:
Now we can render our first element via React! Add this:
```javascript
root.render(
    <React.StrictMode>
        This is a test in index.js.
    </React.StrictMode>
);
```

> `<React.StrictMode>` let React perform additional runtime checks and provides improved error messages.

Now from the terminal, run: `npm start`, Parcel will handle the rest. It will open a new tab in your default browser at "http://localhost:1234/" where you should see "This is a test in index.js." displayed at the top left of the page.

* We can safely delete "This is a test in index.js.", import `App.js` and render it here:
```javascript
import React from "react"
import ReactDOM from "react-dom/client"
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);
```

### 8. App.js

* Import React and Bootstrap

In each React javascript file, we need to import the React module. But here in `App.js`, we need to import `bootstrap/dist/css/bootstrap.min.css` and `bootstrap/dist/js/bootstrap.bundle.min.js`
```javascript
import React from 'react'
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'
import '../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js'
```

> The Bootstrap JavaScript file (bootstrap.bundle.min.js) includes both Bootstrap's JavaScript and Popper.js, and it's responsible for enabling various Bootstrap components that rely on JavaScript functionality, such as dropdowns (which we have in our NavBar), modals, tooltips, etc.
If you are trying [Sass](https://getbootstrap.com/docs/5.3/customize/sass/#importing), don't forget to remove the Bootstrap imports in this section as they may override your customizations, causing unintended conflicts or style inconsistencies.

* Create functional component and export it:
```javascript
function App() {
    return (
        <div className='App'>
            This is a test in App.js.
        </div>
    );
}

export default App;
```

> Alternatively, you can streamline your code by using `export default function App(){}` and omitting the last line if you only have a single component to export.


This time you should see "This is a test in App.js." displayed at the top left of the page with a Bootstrap default font style (much better).

* Import components
```javascript
import React from 'react'
import NavBar from './components/NavBar'
import Content from './components/Content'
import Footer from './components/Footer'
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'
import '../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js'

function App() {
    return (
        <div className='App'>
            <NavBar />
            <Content />
            <Footer />
        </div>
    );
}

export default App;
```
Remove our test text and import child components `NavBar` `Content ` and `Footer` which we will handle shortly. Please Note that all the child components should be placed in a single container, in our case, `div className='App'`.

### 9. Fulfil our components

These children-components' behaviours are just like the `App.js` we just did -- In the `return()` section, simply copy and paste your preferred Bootstrap code. Just ensure that all the formatting and class names are accurate and up-to-date. 

I have included some default components like Navbar and Card from Bootstrap for you. Additionally, I have added a simple footer to give the website a more professional touch. You can review the GitHub repository and extract the code from the following three JavaScript files: `Navbar.js` `Content.js` `Footer.js`. Then, integrate this code into your respective files. 

This is an example of `Navbar.js`:
```js
import React from "react"

export default function Navbar() {
    return (
        <nav class="navbar navbar-expand-lg bg-body-tertiary">
            <div class="container-fluid">
                <a class="navbar-brand" href="#">Navbar</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                        <li class="nav-item">
                            <a class="nav-link active" aria-current="page" href="#">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Link</a>
                        </li>
                        <li class="nav-item dropdown">
                            <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                                Dropdown
                            </a>
                            <ul class="dropdown-menu">
                                <li><a class="dropdown-item" href="#">Action</a></li>
                                <li><a class="dropdown-item" href="#">Another action</a></li>
                                <li><hr class="dropdown-divider" /></li>
                                <li><a class="dropdown-item" href="#">Something else here</a></li>
                            </ul>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link disabled" aria-disabled="true">Disabled</a>
                        </li>
                    </ul>
                    <form class="d-flex" role="search">
                        <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search" />
                        <button class="btn btn-outline-success" type="submit">Search</button>
                    </form>
                </div>
            </div>
        </nav>
    )
}
```

You can discover more official ready-to-use components on your own at [Bootstrap](https://getbootstrap.com/docs/5.3/getting-started/introduction/). 

### 10. Start it up!
If your webpage encounters any issues, simply press `Ctrl + C` in the terminal to terminate it. Then, restart your project by running `npm start` again.

Now you'll have a fully functional React app displayed in your default browser at "http://localhost:1234/" with a navbar, content section and a footer. 

![navbar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mtnkxqajo03qj0ikcb8c.png)

![footer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k1gp6jn3aggawcj3zfbc.png)




Don't forget to add `.gitignore` in your root to exclude large dependencies files from version control. And now you can start customising your page using React components with Bootstrap. 

Please kindly let me know if there is any inaccuracy.

Happy coding.