Create a React Blog Site | Beginner Project for Jr. Devs
Tags: react, webdev, portfolio, codenewbie
Published: 2021-04-23 13:46:44

### <center>Create a React Blog Site | Beginner Project for Jr. Devs</center>

------------

#### <center>Browse our [Teachable](http://anobject.teachable.com "Teachable") courses.</center>

------------

![Create a React Blog Page](https://user-images.githubusercontent.com/58220766/115167966-64f8fb00-a087-11eb-90ed-c33a948b551d.png)

### We'll build this webpage out of 6 components.

1. **BlogPage.js** - the main container for our posts
2. **Post.js** - a single blog post
3. **WriteUp.js** - a place to show your copy-write
4. **Gallery.js** - an image gallery
5. **PrimaryAsset.js** - a place to show a large print image or embed a video
6. **Separator.js** - a simple design to separate each blog post

All of the information displayed in a blog post will be seeded in through a **feeder file**.

This file will have the following schema:

<br />

```
[
    {
        title: ``,
        subtitle: ``,
        images: [``],
        primary_asset: ``,
        copywrite: [``, ``]
    },
    {
        title: ``,
        subtitle: ``,
        images: [ ],
        primary_asset: ``,
        copywrite: [ ]
    }
]
```

<br />

Each blog post will have a **title**, **subtitle**, an **array of images** for our gallery, an **HTML string** for a **main/primary asset**, and an **array of 2 HTML strings** for the **copy-write**.

------------

### BlogPage.js

#### Our container for our blog posts.

Our main component, the **BlogPage** will be broken up into 4 sections.

1. A site header.
2. A page name.
3. Left side for blog posts.
4. Right side for an index/table of contents.

<br />

```
<div className="blog_page">
    <div className="site_header">

    </div>

    <div className="page_name">
    </div>

    <div className="container">
        <div className="left_side">
            <div className="blog_posts">

            </div>
        </div>
        <div className="right_side">
            <div className="blog_index">

            </div>
        </div>
    </div>
</div>
```

<br />

![blogpage](https://user-images.githubusercontent.com/58220766/115173845-2159bd80-a096-11eb-8613-79ca89510050.png)

------------

### Post.js

#### Each post we make is contained within this component.

In here, we can design any type of post we want.

For this tutorial, we'll have **five sections**.

Sections for...

the post title...

some copywrite...

an image gallery...

some more copy-write...

and finally a primary or main asset (video or large print image).

<br />

```
<div className="blog_post">
    <div className="section section1">
        // TITLE
    </div>

    <div className="section section2">
        // COPYWRITE
    </div>

    <div className="section section3">
        // GALLERY
    </div>

    <div className="section section4">
        // COPYWRITE
    </div>

    <div className="section section5">
        // MAIN ASSET (VIDEO OR IMAGE)
    </div>
</div>
```

<br />

![post](https://user-images.githubusercontent.com/58220766/115175435-f6bd3400-a098-11eb-803d-35c2b1d665ba.png)

------------

### WriteUp.js

#### We're going to take a piece of copy-write and add two visual flairs.

We need to find a way to hide part of the post.

If the copy-write is 700 lines long, we don't want to show all 700 lines.

We want to hide the copy-write up to a specified height and then give the user the option of showing the entire copy-write.

To accomplish this, we'll initially load up the copy-write through the '**dangerouslySetInnerHTML**' prop of our **div** element.

<br />

```
<div ref={CopyWriteRef} dangerouslySetInnerHTML={{__html: props.copywrite}}>
</div>
```

<br />

Once the component loads, we'll check it's height. If the total height of our **div** once rendered is greater than a certain threshold, we'll cut the height down to that threshold.

<br />

```
useEffect(() => {
    const copywrite = CopyWriteRef.current;

    if (copywrite.getBoundingClientRect().height > text_threshold) {
        copywrite.style.height = `${text_threshold}px`;
        copywrite.nextSibling.style.display = 'block';
        copywrite.nextSibling.nextSibling.style.display = 'block';
    }
});
```

<br />

We also show a **linear-gradient** at the bottom of the copy-write as well give the user a **read more** button.

<br />

![writeup](https://user-images.githubusercontent.com/58220766/115480473-89381180-a218-11eb-8ca9-e51262fd8a7b.png)

------------

### Gallery.js

#### A simple CSS grid-styled DIV will create our image gallery.

We'll define our gallery in **1 row** by **2 columns** for **Desktop** and **1 x 1** for **Mobile**.

<br />

```
.post_image_gallery {
    width: fit-content;
    height: fit-content;
    max-height: calc((270px * 2) + 20px);
    display: grid;
    gap: 10px;

    grid-template-rows: 270px;
    grid-template-columns: repeat(2, 270px);
    grid-auto-rows: 270px;

    justify-content: center;
    overflow-x: hidden;
}
```

<br />

![gallery](https://user-images.githubusercontent.com/58220766/115481006-a7524180-a219-11eb-9dc3-e34424e8079d.png)

------------

### PrimaryAsset.js

#### A simple DIV where we show an image or video (iframe embed).

Just like the **WriteUp.js** component, we'll insert our **image** or **iframe** embed in the '**dangerouslySetInnerHTML**' prop of our **DIV**.

For this project, we'll use an **iframe embed** from our **feeder file**.

<br />

```
primary_asset: `<iframe src="https://www.youtube.com/embed/cAC4s5GuUb8" \
title="YouTube video player" frameborder="0" allow="accelerometer; \
autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" \
allowfullscreen></iframe>`,
```

<br />

```
<div dangerouslySetInnerHTML={{__html: props.primary_asset}}>
</div>
```

<br />

![primaryasset](https://user-images.githubusercontent.com/58220766/115482750-5cd2c400-a21d-11eb-9f28-8b7fd11883dd.png)

------------

### Separator.js

#### The final component. Just a few lines to separate one post from another.

We'll just place three **square icons** from **[Font Awesome](https://fontawesome.com/icons/square-full?style=solid "Font Awesome")** into a **DIV** and space them apart.

<br />

```
<div className="separator">
    <i className="fas fa-square-full"></i>
    <i className="fas fa-square-full"></i>
    <i className="fas fa-square-full"></i>
</div>
```

<br />

![separator](https://user-images.githubusercontent.com/58220766/115483770-6ceba300-a21f-11eb-9e65-7e12f3ff21a7.png)

------------

### There is much more nuance to this project.

You can view our video tutorial down below.

You can get the source files [here](https://github.com/an-object-is-a/react-webpage-04 "here").

------------

#### <center>If you want a more in-depth guide, check out my full video tutorial on YouTube, **[An Object Is A](https://www.youtube.com/c/anobjectisa "An Object Is A")**.</center>

### <center>Create a React Blog Site | Beginner Project for Jr. Devs</center>

{% youtube 1qZE0HUclfA %}