Get A Blog On Your Website with React and WordPress API

Sam Williams - Jan 22 '18 - - Dev Community

I’ve been reading a lot of articles over the last few months and one thing that I often noticed was disclaimers at the start saying that these posts were originally from their own website. Having written a few articles and wanting to increase my exposure, I decided that I wanted to have a blog on my site as well. But how to do it?

Options

There were a few possible options for incorporating a blog into my site but the main two are a custom content management system (CMS) or WordPress. I wanted to get it set up quickly so I went with using WordPress.

WordPress API

I’d heard a few things about the WordPress API over the last few weeks so started to Google. I set up a free blog at WordPress.com and imported my articles from Medium. This was super simple with Mediums export facility and WordPress’s “import from Medium” facility.

Now I had my articles on WordPress I had to figure out how to access them. I found this page in the documentation and I built a very basic web page to test with.

<h1>wordpress checker</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="getWordpress.js"></script>
Enter fullscreen mode Exit fullscreen mode
console.log("this is a proof of concenpt");

$.get(
  "http://public-api.wordpress.com/rest/v1/sites/YourSite.wordpress.com/posts",
  function(response) {
    console.log(response);
  }
);
Enter fullscreen mode Exit fullscreen mode

This does the very simple task of calling the WordPress API and asking for all of the posts from “YourSite.wordpress.com”. From this I got a response object containing the number of posts and an array of each of the posts.

Routing

Now that I was going to have a Blog section to my site, I had to change from the single page that I previously had. I installed react-router-dom and imported BrowserRouter and Route into my layout file.

<BrowserRouter>
    <div id="center-stripe">
        <Nav />
        <Route exact path="/" component={main} />
        <Route exact path="/blog" component={Blog} />
    </div>
</BrowserRouter> 
Enter fullscreen mode Exit fullscreen mode

Creating the Blog in React

My personal website is built using create-react-app and has a very basic structure. The next thing that I needed to do was to add a new “blog” page on which all of the article previews would be shown.

export default class Blog extends Component {
  constructor(props) {
    super(props);
    this.state = {
      posts: []
    };
  }
  componentDidMount() {
    axios
      .get(
        "http://public-api.wordpress.com/rest/v1/sites/samwcoding.wordpress.com/posts"
      )
      .then(res => {
        this.setState({ posts: res.data.posts });
        console.log(this.state.posts);
      })
      .catch(error => console.log(error));
  }

  render() {
    return (
      <div className="blog">
        <h1 className="sectionTitle">Articles</h1>
        {this.state.posts.map(post => <ArticlePreview post={post} />)}
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

I’ll talk you through this code. The top section sets the state of the component with an empty array of posts. Then I use the componentDidMount function to execute the call to the WordPress API with axios. When the API call returns, I set this.state.posts to be the array of posts. This then causes line 24 to render an ArticlePreview component for each of the posts.

render() {
  if (this.props.post) {
    return (
      <div className="article">
        <a href={"/blog/" + this.props.post.ID} className="blackLink">
          {this.props.post.featured_image ? (
            <img
              className="img-responsive webpic"
              alt="article header"
              src={this.props.post.featured_image}
            />
          ) : (
            ""
          )}
          <h1 className="text-center">{this.props.post.title}</h1>
          <div className="content">{excerpt}</div>
        </a>
        <Link to={"/blog/" + this.props.post.ID}>
          <button className="btn">Read More</button>
        </Link>
      </div>
    );
  } else {
    return null;
  }
}
Enter fullscreen mode Exit fullscreen mode

ArticlePreview takes each post and renders the preview with a title and excerpt, which are both provided by the WordPress API. If the post also has a featured image, it includes that too.

Preview from the wordpress API

I reused a lot of the CSS from the rest of the website to style the articles previews and it looks quite good. One major error is the “

I’” and similar bits dotted throughout the excerpt. To solve this I set the excerpt to run though a removeUnicode() function before being rendered to the screen. It simply replaced all &#8217 with just a comma and removed the <p> and [&hellip;] tags. Its not elegant but it works.

Now I had the list of posts, I had to create a component for whole articles. I added another route for /blog/:id and started on the new component. It was almost identical to the ArticlePreview component, except that instead of rendering just the excerpt, it would render just one article. Getting the article from WordPress was very simple, just adding the article ID onto the end of the previous API call.

axios.get(
    "http://public-api.wordpress.com/rest/v1/sites/samwcoding.wordpress.com/posts/" +
    this.props.match.params.id
)
Enter fullscreen mode Exit fullscreen mode

Getting the article response is where I hit my first stumbling block. The body of the article was all in stringified HTML format. I found a solution with the dangerouslySetInnerHTML function. (If anyone has any suggestions on how to implement this better then please let me know).

Working Article

With this done I had a few changes to make. The nav buttons at the top just connected to anchor tags and that worked fine on a single page website but now they were sending users to /blog#about which doesn’t work. This was solved by defining the link specifically as /#about and /#projects.

The blog now works well with the number of articles I currently have written but how will it cope when there are 50 or 100 articles? In the future I may have to render a few of the article previews at a time, rendering more if the user scrolls to the bottom. Another feature I could add would be searching.

Checkout the blog at SamWSoftware blog and view my whole code here.

. . . . . . . . . . . . . . . . . . . . . . . .