React Quick start guide

Estimated duration: 10 minutes

This guide shows you how to connect Prepr to a React project to get data from Prepr CMS. You'll learn how to make a simple blog with React and Prepr CMS. By the end of this guide, you'll have a working app that looks like the image below.

blog site end result

Info

Prerequisites

You need to have the following setup before you connect your React project to Prepr.

Step 1: Create a new React project

The instructions below will guide you on how to create an empty React project for your blog app.

Install React

You can skip this step if you have an existing React project.

  1. Open a terminal and execute the command below to create a new React project called prepr-react.
npx create-react-app prepr-react

Note

The create-react-app package is no longer being maintained. Check out the React docs for more details. Also check out our Next Quick start guide to create a new project with a recommended React framework.

  1. Now that the project is successfully created, go to the prepr-react folder, the root directory of the project, and start the project with the following commands in the terminal:
cd prepr-react
npm start
  1. You should now be able to view your app on your localhost, for example, http://localhost:3000/.

  2. Open your project with your preferred code editor.

  3. Update App.js in the src folder with the following code to display your blog:

//  ./src/App.js 

import './App.css';

function App() {
  return (
    <div>
      <h1>My blog site</h1>
    </div>
  );
}


export default App;

You should now see something like the image below on your localhost.

view component

Step 2: Install the Apollo client

The Apollo client is an integration tool that helps to retrieve CMS data with GraphQL. The instructions below show you how to install the Apollo client so that you can add GraphQL queries to request data from the Prepr API.

  1. Stop the server you started in the above step (CTRL-C) and execute the following command in the terminal:
npm install @apollo/client graphql
  1. Go to the src folder and create a services folder. Then, create a file called apollo-client.js in this folder. Copy the following code to this file to import and initialize the Apollo client:
// ./src/services/apollo-client.js

import { ApolloClient, InMemoryCache } from "@apollo/client";

const client = new ApolloClient({
    uri: `https://graphql.prepr.io/${process.env.REACT_APP_PREPR_ACCESS_TOKEN}`,
    cache: new InMemoryCache(),
});

export default client;

This client will be used to make API requests to endpoints provided by the Prepr CMS across your React application.

  1. We recommend using environment variables to store sensitive information like access tokens. To add environment variables, create a .env file in the root directory of your project and add the access token like this:
# ./.env

REACT_APP_PREPR_ACCESS_TOKEN=<YOUR-ACCESS-TOKEN>
  1. Replace the placeholder value <YOUR-ACCESS-TOKEN> with an access token from Prepr. Get an access token by logging into your Prepr account:

a. Go to Settings > Access tokens to view all the access tokens.

b. Copy the GraphQL Production access token to only retrieve published content items on your site.

access token

Note

Use the GraphQL Production access token to request published content items for your live app and use the GraphQL Preview token to make a preview of unpublished content items for your content editors.

  1. Update the index.js file in the src folder to add the ApolloProvider component with the following code:
// ./src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {createBrowserRouter, RouterProvider} from "react-router-dom";

// Import the Apollo Provider and the Apollo client 
import {ApolloProvider} from "@apollo/client";
import client from "./services/apollo-client";

const root = ReactDOM.createRoot(document.getElementById('root'));

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
]);

// Add the ApolloProvider 
root.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <RouterProvider router={router}/>
    </ApolloProvider>
  </React.StrictMode>
);
  1. Install the React Router DOM package to enable routing with the following command:
npm install react-router-dom@6
  1. Execute the following commands to make sure that the Apollo client is installed correctly:
npm install
npm start

If your app runs without errors, then the setup above was done correctly. The next step is to fetch content from Prepr using the installed Apollo client.

Step 3: Fetch multiple articles

Now that your Apollo client is installed and connected to Prepr, fetch the blog articles from Prepr.

Add a GraphQL query

  1. Go to the src folder, create a queries directory and create a file named get-articles.js.

  2. Add the following query to this file to retrieve all articles:

// ./src/queries/get-articles.js

import { gql } from "@apollo/client";

export const GetArticles = gql`
  query {
    Articles {
    items {
      _id
      _slug
      title
    }
  }
 }
`

Tip

You can create and test GraphQL queries using the Apollo explorer from Prepr. Open the API Explorer from the Article content item page in Prepr or the access token page.

If you’re using preloaded demo data in your Prepr CMS environment as mentioned above in the Prerequisites section, you should have a few published articles as shown in the below image. The query will retrieve the ID, Slug, and Title of each article.

demo articles

In the next step, we'll fetch and process the query response.

Fetch data

Now that the query has been added, fetch the articles from Prepr and display them in the app.

  1. Open the App.js file in the src folder and replace the content with the code below to display the data retrieved from the query.
// ./src/App.js

import React from "react";

// Import the query and the apollo client
import {GetArticles} from "./queries/get-articles";
import {useQuery} from "@apollo/client";

function App() {

  // Execute the query
  const {loading, error, data} = useQuery(GetArticles);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  // Set the query results
  const articles = data.Articles.items;

  return (
    <div>
      <h1>My blog site</h1>
      <ul>
        {articles.map((article) => (

          // List the fetched articles
          <li key={article._id}>
            {article.title}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

Now when you view the website on your localhost, you'll see something like the image below.

Local

Step 4: Fetch individual articles

Now that you have the list of articles, add links to them. When a visitor clicks on a link, your app should open a detailed article page automatically. The instructions below show you how to set up the routing from the main page to the detailed page and how to fetch the article details based on the slug of the article that was clicked.

  1. Update the App.js file to include a link tag on each article title as shown in the code below.
// ./src/App.js

import React from "react";
import {GetArticles} from "./queries/get-articles";
import {useQuery} from "@apollo/client";

// Import Link to enable links in the HTML
import {Link} from "react-router-dom";

function App() {
  const {loading, error, data} = useQuery(GetArticles);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  const articles = data.Articles.items;

  return (
    <div>
      <h1>My blog site</h1>
      <ul>
        {articles.map((article) => (
          <li key={article._id}>
            
            {/* Add links to the article title */}
            <Link to={article._slug}>{article.title}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

Now when you view the app, each article has its own link. When you click on the link, a new page opens with the slug in the URL, but a Page 404 error is displayed. Continue with the next step to fetch the article details and resolve this error.

Fetch article details

Add another query to fetch a specific article by its slug and make this page visible when clicking on an article.

  1. Create a file called get-article-by-slug.js in the queries folder and add the following to query a specific article by its slug:
// ./src/queries/get-article-by-slug.js

import { gql } from "@apollo/client";

export const GetArticleBySlug = gql`
query ($slug: String) {
   Article (slug: $slug) {
     _id
     title
     content {
       __typename
       ... on Text {
         body
         text
       }
       ... on Assets {
         items {
           url
         }
       }
     }
   }
}`

Now that the query is added, fetch the individual article by its slug. Fetch the article title and the article content.

Note

  1. Go to the src folder and create a new file called ArticlePage.js with the code below to fetch an article by its slug and display the article details.
// ./src/ArticlePage.js

import React from "react";
import {useQuery} from "@apollo/client";

// Import the query and the apollo client
import {GetArticleBySlug} from "./queries/get-article-by-slug";
import {useParams} from "react-router-dom";

export default function ArticlePage() {

  // Get the slug from the URL
  const {slug} = useParams();

  // Execute the query
  const {loading, error, data} = useQuery(GetArticleBySlug, {
    variables: {slug}
  });

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  const article = data.Article;

  return (
    <>
      <h1>
        { article.title }
      </h1>

     {/* Loop through content types in article content */}

      {article.content.map((contentType) => {

        // Display image if it exists
        if (contentType.__typename === 'Assets' && contentType.items.length) {
          return (
            <div className="my-10">
              <img
                src={contentType.items[0]?.url}
                width="300"
                height="250"
                alt={`Image for ${article.title}`}
              />
            </div>
          )
        }

        // Display text as HTML

        if (contentType.__typename === 'Text') {
          return (
            <div dangerouslySetInnerHTML={{ __html: contentType.body }}></div>
          )
        }
      })}
    </>
  )
}
  1. Finally, update the index.js in the src folder to include the route to the new article page with the following code:
// ./src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

// Import the article page
import ArticlePage from "./ArticlePage";
import {createBrowserRouter, RouterProvider} from "react-router-dom";
import {ApolloProvider} from "@apollo/client";
import client from "./services/apollo-client";

const root = ReactDOM.createRoot(document.getElementById('root'));

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
  // Add a route to the article page
  {
    path: "/:slug",
    element: <ArticlePage />,
  }
]);

root.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <RouterProvider router={router}/>
    </ApolloProvider>
  </React.StrictMode>
);

Now, when you view your site, you can click on an article which will direct you to that specific article like in the image below.

article detail

All done

Congratulations! You have successfully connected a React project to Prepr for a simple Blog app.

Next steps

To learn more on how to expand your project, check out the following resources: